同源策略
同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到的请求的URL的域必须与当前Web页面的域相同。存在以下任一情况,即发生跨域:
- 网络协议不同,如http协议访问https协议;
- 端口不同,如80端口访问8080端口;
- 域名不同,如aaa.com访问bbb.com;
- 子域不同,如abc.qq.com访问123.qq.com。
克服的方法&跨域原理
1. 基于iframe
对于主域名(基础域名)相同而子域名不同的情况,也就是两个页面必须属于同一个基础域,使用同意协议(例如http)和同一端口。可以通过这种方法来解决。可以在http://www.example.com/a.html和http://api.example.com/b.html两个文件中分别添加document.domain = ‘example.com’,然后在a.html中创建一个iframe指向b.html,即a.html是父页面,b.html是个子页面。
www.example.com上的a.html:
<html> <head> <script> document.domain = "example.com"; var ifr = document.createElement('iframe'); ifr.src = 'http://api.example.com/b.html'; ifr.style.display = 'none'; document.body.appendChild(ifr); ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; // 在这里操纵b.html alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue); }; </script> </head> <body> </body> </html>
api.example.com上的b.html
<html> <head> <script> document.domain = "example.com"; function a(){ alert("c"); } </script> </head> <body> </body> </html>
注意:
- 某一页面的domain默认等于window.location.hostname。要注意区分主域名和二级多级域名。
- 可能出现安全问题,如果一个站点www.example.com被攻击,另一个站点api.example.com也会引起安全漏洞。
2. 动态创建script标签
script标签可以访问任何域的资源,不受浏览器同源策略的限制,所以可以通过在页面动态创建script标签的方法来实现跨域。
var script = document.createElement('script'); script.src = "http://www.example.com/js/*.js"; document.body.appendChild(script);
这样就加载到了其他域的js文件,然后可以在本页面内调用加载的js文件中的函数。JSONP就是通过这个方式实现的,实现细节有些不同。
其他跨域方法可以参考以下两篇文章:
http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m3