js跨域访问

本文主要来源于博客园中其他博客:http://www.cnblogs.com/rainman/archive/2011/02/21/1960044.html

浏览器都有一个同源策略,其限制之一就是不能通过ajax的方法去请求不同源中的文档,另外一个限制就是浏览器中不同域的框架之间不能进行js的交互操作。如何来解决这个问题呢?

那当然要用到JS的跨域访问技术.域名地址组成如下:


如果协议、子域名,主域名,端口号中有任何一个不相同,都被当做是不同的域。对于端口号和协议的不同,只能通过后台来解决。针对子域名或者主域名不同的这种跨域来说,解决的方案如下:

第一种:通过修改document.domain来跨子域

不同的框架之间可以获得window 对象,但是无法获得相应的属性和方法。比如,有个页面A,它的地址是http://www.example.com/a.html,在这个页面中嵌入了另外一个页面B,它的地址为http://example.com/b.html。显然,A和B的子域不同,所以我们无法在A页面中获得B中的东西。

<script type="text/javascript">
    function test(){
        var iframe = document.getElementById('ifame');
        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

使用document.domain就可以解决这个问题了。我们可以把http://www.example.com/a.htmlhttp://example.com/b.html。这个两个页面的document.domain都设成相同的域名。但是要注意这个document.domain的设置也是有限制的,我们只能把document.domain设置成自身或者更高一级的父域,且主域必须相同。

  1. 在页面Ahttp://www.example.com/a.html中设置document.domain:
    2.    <iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
    3.    <script type="text/javascript">
    4.        document.domain = 'example.com';//设置成主域
    5.        function test(){
    6.            alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 对象
    7.        }
    8.    </script>

    2. 在页面Bhttp://example.com/b.html中设置document.domain:

    <script type="text/javascript">
        document.domain = 'example.com';//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同
    </script>

第二种:使用window.name来进行跨主域

Window对象有个那么属性,该属性有个特征:在一个窗口(window)的生命周期内,窗口载入的所有页面都共享一个window.name,每个页面对window.name都要读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因为新页面的载入而重置。比如有一个页面A,地址为www.example.com/a.html,需要通过页面A中的js来获取另一个页面B中的数据,B的地址为:www.cnblogs.com/data.html,再增加一个代理页面C,地址为www.example.com/c.html。A 与C是同一域下,可以相互通信。A和B的主域不同,如何进行数据交互呢?

假设页面A想要获取页面B中的数据,data.html页面里的代码很简单,就是给当前的window.name设置一个a.html页面想要得到的数据值。data.html里的代码:

<script type="text/javascript">
window.name="我就是页面A想要的数据,所有可以转化成字符串的数据都可以在这里赋值,比如json字符串"</script>
  1. 先在页面A中使用一个隐藏的iframe来充当中间人的角色,由iframe去获取页面B中的数据。充当中间人的iframe要想获取页面B中通过window.name设置的数据,只需要把iframe的src设置为www.cnblogs.com/data.html
  2. 在页面A上监听iframe的onload 事件,在这个事件中设置这个iframe的src 指向本地域的代理文件C。
  3. 销毁iframe,获取数据后就要销毁iframe,一方面是为了释放内存,另一方面是为了安全(不被其他域的js访问)。
    <script type="text/javascript">
       var state=0;
       iframe=document.createElement('iframe');//动态创建iframe
       iframe.style.display = 'none';
       function onload(){
           if(state==1){
               var data=iframe.contentWindow.name;//读取数据
               console.log(data);
           }else if(state==0){
               state=1;
               iframe.contentWindow.location="www.example.com/c.html";//设置代理文件
           }
           
       };
       iframe.src="www.cnblogs.com/data.html"; 
       if(iframe.attachEvent){
           iframe.attachEvent("onload",onload);
       }else{
           iframe.onload=onload();
       }
       document.body.appendChild(iframe);
       iframe.contentWindow.document.write('');
       iframe.contentWindow.close();
       document.body.removeChild(iframe);
    </script>

 

原文地址:https://www.cnblogs.com/alisayuan/p/5175347.html