首页 > 代码库 > js跨域问题解决方案

js跨域问题解决方案

 


 

1、JSON-P跨域

动态脚本注入的方法,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。

 

2、window.name跨域

indow对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。 
数据大小有限制,大小一般为2M,IE和firefox下可以大至32M左右 
有三个页面: 
a.com/app.html:应用页面。 
a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。 
b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。 
实现起来基本步骤如下:

在应用页面(a.com/app.html)中创建一个iframe,把其src指向数据页面(b.com/data.html)。 
数据页面会把数据附加到这个iframe的window.name上,data.html代码如下:

 
  1. <script type="text/javascript">
  2. window.name = ‘I was there!‘; // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右
  3. // 数据格式可以自定义,如json、字符串
  4. </script>

在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,所以可以相互通信)。app.html部分代码如下:

 
  1. <script type="text/javascript">
  2. var state = 0,
  3. iframe = document.createElement(‘iframe‘),
  4. loadfn = function() {
  5. if (state === 1) {
  6. var data = iframe.contentWindow.name; // 读取数据
  7. alert(data); //弹出‘I was there!‘
  8. } else if (state === 0) {
  9. state = 1;
  10. iframe.contentWindow.location = "http://a.com/proxy.html"; // 设置的代理文件
  11. }
  12. };
  13. iframe.src = ‘http://b.com/data.html‘;
  14. if (iframe.attachEvent) {
  15. iframe.attachEvent(‘onload‘, loadfn);
  16. } else {
  17. iframe.onload = loadfn;
  18. }
  19. document.body.appendChild(iframe);
  20. </script>

获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。

 
  1. <script type="text/javascript">
  2. iframe.contentWindow.document.write(‘‘);
  3. iframe.contentWindow.close();
  4. document.body.removeChild(iframe);
  5. </script>

总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。 
引自:http://www.cnblogs.com/rainman/archive/2011/02/21/1960044.html

 

3、HTML5中新引进的window.postMessage方法跨域

window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

调用postMessage方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * 。 
缺点是IE6、IE7不支持

 

4、iframe+document.domain来跨子域

我们只要把http://www.example.com/a.html 和 http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。

js跨域问题解决方案