这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
特别注意两点:
#1、如果是协议和端口造成的跨域问题“前台”是无能为力的;
#2、在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
要解决跨域的问题,我们可以使用以下几种方法:
方法一、通过jsonp跨域
JSONP包含两部分:回调函数和数据。
回调函数:当响应到来时要放在当前页面被调用的函数。
数据:就是传入回调函数中的json数据,也就是回调函数的参数了。
/*handleResonse({"data": "zhe"})*/ //原理如下: //当我们通过script标签请求时 //后台就会根据相应的参数(json,handleResponse) //来生成相应的json数据(handleResponse({"data": "zhe"})) //最后这个返回的json数据(代码)就会被放在当前js文件中被执行 //至此跨域通信完成 //1、使用JS动态生成script标签,进行跨域操作 function handleResponse(response){ console.log('The responsed data is: '+response.data); //处理获得的Json数据 } var script = document.createElement('script'); script.src = 'http://www.example.com/data/?callback=handleResponse'; document.body.insertBefore(script, document.body.firstChild); -------------------------- //2、手动生成script标签 function handleResponse(response){ console.log('The responsed data is: '+response.data); //处理获得的Json数据 } <script src="http://www.example.com/data/?callback=handleResponse"></script> -------------------------- //3、使用jQuery进行jsonp操作 //jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁 //$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。 <script> $.getJson('http://www.example.com/data/?callback=?',function(jsondata){ //处理获得的Json数据 }); </script>
jsonp虽然很简单,但是有如下缺点:
#1)安全问题(请求代码中可能存在安全隐患) #2)要确定jsonp请求是否失败并不容易
方法二、通过document.domain+iframe来跨子域(只有在主域相同的时候才能使用该方法)
浏览器同源策略限制:
#(1)不能通过ajax的方法去请求不同源中的文档。 #(2)浏览器中不同域的框架之间是不能进行js的交互操作的。
所以,在不同的框架之间(父子或同辈),是能够获取到彼此的window对象的,但不能使用获取到的window对象的属性和方法(html5中的postMessage方法是一个例外),总之,你可以当做是只能获取到一个几乎无用的window对象。
例如,在一个页面 http:// www.example.com/a.html 中,有一个iframe框架它的src是http:// example.com/b.html, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获取iframe中的东西的:
1 // http://www.example.com/a.html 页面中 2 <script> 3 function onLoad(){ 4 var iframe = document.getElementById('iframe');