zoukankan      html  css  js  c++  java
  • javascript 跨域

    跨域:协议、域名、端口 任何一项不同即为跨域.

    一般 js 涉及到的跨域场景包括: ajax 请求的跨域、 cookie 跨域共享(子域名跨域)、iframe 与 parant 的 window 之间的消息传送。

    1、jsonp 不受跨域限制,需要目标服务器配合输出指定 js 代码。

    2、域名不同,但主域名相同的窗口,可以修改 document.domain = "主域名" 来实现同源(同理,还有 cookies 的共享设置也是通过这种方法),这种方法可以使一级 XMLHttpRequest 实现通讯。

    3、websocket 将 http 协议升级为 ws 协议。

    4、二级 XMLHttpRequest 跨域: 服务器返回响应头 Access-Control-Allow-Origin:请求方域名,浏览器发往服务器的 origin 请求头包含了请求方域名,这是由浏览器的 XMLHttpRequest  对象自动发送的,并且不能修改。 IE8+ 可以使用 XDomainRequest 。

    // XMLHttpRequest level2
    var params = 'a=1&b=2';
    var method = 'post';
    var url = 'http://www.api.com/xcross.php';
    var async = true;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if(this.readyState==4&&this.status==200){
            console.log(this.responseText);
        }
    }
    xhr.open(method, url, async); 
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //post 普通字符串参数
    xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"); 
    xhr.setRequestHeader("Myheard","this is a request header of contract"); xhr.send(params);
    //XMLHttpRequest level2 的服务器响应 php
    
    //可将允许跨域请求的域名设置为 * ,表示不限制请求来源
    header('Access-Control-Allow-Origin:http://localhost'); 
    
    /*
    允许浏览器发来的 request 头信息,尤其是想要自定义头信息时应该在这里约定,否则请求会被禁止
    比如允许浏览器发送一个名为 Myheard 的自定义 请求头.
    最好设置一下 Content-Type ,
    浏览器使用 xhr 的 post 方式进行求 ajax 请求时,
    可能会默认发送 content-type:application/xml (chrome浏览器),这可能不被服务器接受(取决于服务器默认配置参数),
    而且 post 普通字符串参数时不应该 使用 application/xml,应该在 js 设置 Content-Type:application/x-www-form-urlencoded X-Requested-With 请求头可用于判断浏览器端请求方式
    */ header('Access-Control-Allow-Headers:Origin, Content-Type, X-Requested-With, Accept, Myheard'); //输出数据 echo json_encode(array('x'=>123,'y'=>456));

      

    5、 iframe 窗口与父窗口在跨域情况下,可以互相获取 window 对象(iframeNode.contentWindow、 window.parent),但不能访问 window 对象的属性,topWindow 不能获取 iframe 中 的 iframe window 对象(因为无法获取 iframe 中的 iframeNode),反之却可以 (window.parent.parent)。

    6、window.name 属性在 location.href 被修改后仍然保留,parent 中修改 iframe 的 src 为同域名后可以访问 iframe 的 window.name 。

    7、iframe 窗口在跨域情况下虽然不能访问 window 的属性值,却可以修改 window.location.href,修改 location.href 的锚点不会发起请求,甚至在访问跨域的子窗口也被禁止的情况下,location.href 的修改也能成功,比如一个跨域的 iframe 内修改父页面中的另一个跨域的 iframe 的地址: 

    //由于 iframe 跨域,访问父页面的 frames 其实是被禁止的,但是设置 location.href 可以成功
    parent.frames['otheIframe'].location.href = "http://www.cnblogs.com/ecalf/"; 

     8、IE 6、7下,跨域的 iframe window 可以共享 window.navigator,可以通过自定义 window.navigator 上的属性来达到跨域,这种跨域方式可以直接传 js 对象型数据。

    9、window.postMessage:适用于IE8+,FF,Chrome,opera 等较新的浏览器。

    获取 window 对象(包括 iframeNode.contentWindow、window.open 创建的窗口,当然也可以蛋痛地向本窗口 postMessage )后使用 HTML5 的window.postMessage 方法, iframeNode.contentWindow.postMessage("msg"," * 或 contentWindow中的域名") ,在 iframe 中使用 window.onmessage 事件实现跨域消传送,注意,iframe 在加载完毕后,父窗口 的 onload 事件才触发,不要在 onload 事件之前( iframe 加载完毕前)就 postMessage。

    <iframe id="xx1" src="http://localhost/test/2.html"></iframe>
    <script>
    console.log('hello world');
    window.onload = function(){
        var win = document.getElementById('xx1').contentWindow;
        win.postMessage('post message:hello world','http://localhost');        
    };
    </script>
    //http://localhost/test/2.html  接收 postMessage 的消息
    function receiveMessage(e){
        console.log(e);
        alert(e.data+',from:'+e.origin);
    }
    window.addEventListener("message", receiveMessage, false);

    10、window.name 和 location.hash 存储的信息比较少,不适用单次的大数量传输,window.name 没有消息送达的提示方式,靠定时轮询检测,IE 6/7 没有 onhashchange 事件(该事件绑定在 window 或 body 上,IE8+ 和其他较新的浏览器支持该事件),也靠定时检测。

    11、借助 flash 和 在 server 发送的跨 域请求(本方服务器转发,或者要求跨域服务器处理请求后跳转到本方指定URL,比如使用js  post 一个表单到跨域服务器,对方处理后转跳到本方服务器的URL),这已超出 javascript 范畴,3、4、9 方法不适用于古董级浏览器,对于 window 属性的读取限制多发生在 比较新的浏览 器(比如 opera),一般这些浏览器都支持 postMessage,可以通过检测手段优先使用 postMessage

     综上总结可以看到:跨主域的通讯总是需要对方服务器配合(输出指定的js代码:比如postMessage ,jsonp,页面跳转,或信息头:Access-Control-Allow-Origin,或提供中转用的页面)支持才能实现,ie 6 7 的 navigator 是个BUG 例外。

    关于cookie 的javascript 访问禁止及 跨域时的“第三方 cookie” 参考下面连接:

    http://hi.baidu.com/ecalf830/item/00d142d8b66a38e2795daa48

  • 相关阅读:
    【跃迁之路】【461天】刻意练习系列220(2018.05.12)
    【跃迁之路】【461天】刻意练习系列220(2018.05.12)
    【跃迁之路】【461天】刻意练习系列220(2018.05.12)
    Ajax打开三种页面的请求
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/ecalf/p/2786368.html
Copyright © 2011-2022 走看看