说明 | URL | 是否允许跨域 |
1、同一域名下 | http://www.a.com/a.js | 允许 |
http://www.a.com/b.js | ||
2、同一域名下不同文件夹 | http://www.a.com/a/a.js | 允许 |
http://www.a.com/b/a.js | ||
3、同一域名不同端口 | http://www.a.com:8090/a.js | 不允许 |
http://www.a.com/a.js | ||
4、同一域名不同协议 | http://www.a.com/a.js | 不允许 |
https://www.a.com/b.js | ||
5、域名和域名对应的IP | http://www.a.com/a.js | 不允许 |
http://172.25.32.219/a.js | ||
6、主域相同,子域不同 | http://www.a.com/a.js | 不允许 |
7、不同域名 | http://www.a.com/a.js | 不允许 |
即域名、协议、端口,三者中若有一个不相同,则会出现跨域问题。
解决方法:
1、设置document.domain属性(适合同一主域下不同子域间的通信)
对于主域相同而子域不同的情况(上述表格6),可以通过修改document的domain属性来解决。由于同源策略认为域和子域隶属于不同的域,那么我们
无法在a.com/a.js中访问kpm.a.com/b.js。可以在a.js中设置document.domain=a.com,此时浏览器就会认为它们处于同一个域下,这样两个文件之
间就可以正常通信了。
2、window.name方式(适合单向的数据请求)
window.name属性是一个很特别的属性,当该window的location变化,然后重新加载,name属性可以依然保持不变。所以我们可以在页面 a.html中
用iframe加载b.html,在b.html中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,在a.html修改iframe的地址,将其变成
代理文件proxy.html(proxy.html与a.html在同一个域名下,可以通信),然后就可以读出window.name的值了(最大支持2M数据量)。
function crossDomain() {
var data = '';
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
var _load = function() {
try{
data = iframe.contentWindow.name;
}catch(e) {
iframe.contentWindow.location= 'http://www.a.com/proxy.html';
}
if(iframe.attachEvent) {
iframe.attachEvent('onload', _load);
} else {
iframe.onload = _load;
}
iframe.src = 'http://www.b.com/b.html';
//为不让其他域的js访问name,最后销毁iframe
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
return data;
};
3、动态创建js(只能加载js文件)
script标签本身就可以访问其它域的资源,不受浏览器同源策略的限制,可以通过在页面动态创建script标签,代码如下:
var script = document.createElement('script');
script.src = "XXX";
document.body.appendChild(script);
这样通过动态创建script标签就可以加载其它域的js文件,然后通过本页面就可以调用加载后js文件的函数。缺陷是不能加
载其它域的文档,只能是js文件。
4、使用HTML5的window.postMessage(很酷的新技术)
window.postMessage是HTML5定义的一个很新的方法,使用它可以很方便地进行跨文档消息传输Cross Document Messaging。
语法:
otherWindow.postMessage(message, targetOrigin);
· targetOrigin:发送消息的文档所在的域,例如" http://www.a.com"
processMessage(event.data); //处理接收到的数据
$.ajax({
type: 'get',
async: false, //注意区别jsonp和ajax实质,一个是动态创建<script>,一个是通过xhr对象操作,jsonp并不支持async
url: 'www.example.com/demo.phtml?var=test',
dataType: 'jsonp',
jsonp: 'cb', //传递给请求页面获取回调函数的参数名,默认为callback
jsonCallback: 'handler' //自定义jsonp的回调函数名,若不指定,则jQuery自动生成
});