Ajax跨域问题
2013-08-29 16:52 龙恩0707 阅读(541) 评论(0) 编辑 收藏 举报JavaScript 是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档 在同一域下的内容。
JavaScript 这个安全策略在进行多iframe或多窗口编程、以及Ajax编程时显得尤为重要。根据这个策略,在hitao.com下的页面中包含的 JavaScript代码,不能访问在taobao.com域名下的页面内容;甚至不同的子域名之间的页面也不能通过JavaScript代码互相访问。 对于Ajax的影响在于,通过XMLHttpRequest实现的Ajax请求,不能向不同的域提交请求,例如,在abc.example.com下的页面,不能向def.example.com提交Ajax请求,等等。
一: 不同的子域跨域技术。
首先为了在本地电脑做demo 我们只需要在host分别绑定如下:127.0.0.1 abc.example.com 127.0.0.1 def.example.com 即可 然后假如在def.example.com域下有这么一个页面iframe1.html,JS代码为如下一个函数function test(){
console.log(1);
};
页面我想嵌套abc.example.com域下一个iframe <iframe src="http://abc.example.com/iframe/iframe2.html"></iframe> 然后再iframe2.html页面通过 console.log(window.top.test());这么一句代码去调用def.example.com域下iframe1.html的test函数。
好,我们注意到,这个调用是被前面讲到的“同源策略”所禁止的,JavaScript引擎会直接抛出一个异常。
为了实现上述调用,我们可以通过修改两个页面的domain属性的方法做到。例如,我们可以将上面在abc.example.com和def.example.com下的两个页面的顶端都加上如下的JavaScript代码片段:
document.domain = 'example.com';
这样,两个页面就变为同域了,前面的调用也可以正常执行了。
这 里需要注意的一点是,一个页面的document.domain属性只能设置成一个更顶级的域名(除了一级域名),但不能设置成比当前域名更深层的子域 名。例如,abc.example.com的页面只能
将它的domain设置成example.com,不能设置成 sub.abc.example.com,当然也不能设置成一级域名com。
上面的例子讨论的是两个页面属于iframe嵌套关系的情况,当两个页面是打开与被打开的关系时,原理也完全一样。
二:完全不同域的跨域技术:
1.通过JSONP实现跨域
利用在页面中创建<script>节点的方法向不同域提交HTTP请求的方法称为JSONP,这项技术可以解决跨域提交Ajax请求的问题。JSONP的工作原理如下所述:
假设在http://example1.com/index.php这个页面中向http://example2.com/getinfo.php提交 GET请求,我们可以将下面的JavaScript代码放在http://example1.com/index.php这个页面中来实现:
var eleScript= document.createElement("script"); eleScript.type = "text/javascript"; eleScript.src = "http://example2.com/getinfo.php"; document.getElementsByTagName("HEAD")[0].appendChild(eleScript);
当GET请求从http://example2.com/getinfo.php返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来负责调用http://example1.com/index.php页面中的一个callback函数。
JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以 运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
2. 通过iframe + form表单可以实现“post方式异步跨域”。
思路: 1.通过动态创建iframe 和 动态创建 form表单 iframe的name的值与form表单target相同就可以实现异步跨域。把要传递的数据放在隐藏input里面。
代码如下:
<div class="aa">aaaa</div> <script> $('.aa').click(function(){ crossDomainPost(); }); function crossDomainPost() { // Add the iframe with a unique name var iframe = document.createElement("iframe"); var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING"; document.body.appendChild(iframe); iframe.style.display = "none"; iframe.contentWindow.name = uniqueString; // construct a form with hidden inputs, targeting the iframe var form = document.createElement("form"); form.target = uniqueString; form.action = "http://def.example.com/iframe/iframe2.html"; form.method = "POST"; // repeat for each parameter var input = document.createElement("input"); input.type = "hidden"; input.name = "test"; input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE"; form.appendChild(input); document.body.appendChild(form); form.submit(); } </script> 思想来源 http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript