• 规避同源


    document.domian  iframe
    (在两个页面设置document.domain,  在其中一个页面添加一个隐藏的						iframe指向另外一个页面)
    location.hash iframe
    (在c1页面添加隐藏的iframe指向另外一个页面,可传输hash,
    c2页面向父页面传递数据借助c1域名下一个代理iframe,传输hash)
    windom.name iframe
    (iframe.src属性由外域转向本地域,跨域数据由iframe的window.name从外域传向本地域)
    html5 postmessage
    

    目前有三种方法,可以解决跨域窗口的通信问题。

    片段识别符(fragment identifier)
    window.name
    跨文档通信API(Cross-document messaging)
    

    目前,如果非同源,共有三种行为受到限制。
    (1) Cookie、LocalStorage 和 IndexDB 无法读取。
    (2) DOM无法获得。
    (3) AJAX 请求不能发送。

    1.1、JSONP

    JSONP是利用浏览器对script的资源引用没有同源限制,通过动态插入一个script标签,当资源加载到页面后会立即执行的原理实现跨域的。JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback或者开始就定义一个回调方法,参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
      JSONP只支持GET请求而不支持POST等其它类型的HTTP请求,它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题,JSONP的优势在于支持老式浏览器,弊端也比较明显:需要客户端和服务端定制进行开发,服务端返回的数据不能是标准的Json数据,而是callback包裹的数据。

    1.2、CORS

    CORS是现代浏览器支持跨域资源请求的一种方式,全称是"跨域资源共享"(Cross-origin resource
    sharing),当使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
      CORS与JSONP的使用目的相同,但是比JSONP更强大,CORS支持所有的浏览器请求类型,承载的请求数据量更大,开放更简洁,服务端只需要将处理后的数据直接返回,不需要再特殊处理。

    1.cookie规避同源
    document.domain iframe
    具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;

    document.domain = 'a.com';
    var ifr = document.createElement('iframe');
    ifr.src = 'http://script.a.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.a.com上的b.html

    document.domain = 'a.com';
    

    2.dom规避同源

    document.domain
    iframe location.hash
    这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。原理是利用location.hash来进行传值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash,改变hash并不会导致页面刷新,所以可以利用hash值来进行数据传递,当然数据容量是有限的。假设域名a.com下的文件cs1.html要和cnblogs.com域名下的cs2.html传递信息,cs1.html首先创建自动创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面,这时的hash值可以做参数传递用。cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据(由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于a.com域名下的一个代理iframe;Firefox可以修改)。同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一点有变化则获取获取hash值。代码如下:

    先是a.com下的文件cs1.html文件:

    function startRequest(){
        var ifr = document.createElement('iframe');
        ifr.style.display = 'none';
        ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
        document.body.appendChild(ifr);
    }
    
    function checkHash() {
        try {
            var data = location.hash ? location.hash.substring(1) : '';
            if (console.log) {
                console.log('Now the data is '+data);
            }
        } catch(e) {};
    }
    setInterval(checkHash, 2000);
    

    cnblogs.com域名下的cs2.html:

    //模拟一个简单的参数处理操作

    switch(location.hash){
        case '#paramdo':
            callBack();
            break;
        case '#paramset':
            //do something……
            break;
    }
    
    function callBack(){
        try {
            parent.location.hash = 'somedata';
        } catch (e) {
            // ie、chrome的安全机制无法修改parent.location.hash,
            // 所以要利用一个中间的cnblogs域下的代理iframe
            var ifrproxy = document.createElement('iframe');
            ifrproxy.style.display = 'none';
            ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';    // 注意该文件在"a.com"域下
            document.body.appendChild(ifrproxy);
        }
    }
    

    a.com下的域名cs3.html
    //因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值

    parent.parent.location.hash = self.location.hash.substring(1);
    

    当然这样做也存在很多缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等……

    window.name

    html5postMessage

    3.ajax规避同源
    CORS
    JSONP
    websocket是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
    无跨域问题。

  • 相关阅读:
    Systemd 指令
    2018年书单
    2017年书单
    Centos7 Devstack [Rocky] 重启后无法联网
    kvm虚拟机操作相关命令及虚拟机和镜像密码修改
    负载均衡原理-转
    用配置文件里面的参数值替换yaml模板中的变量值【python】
    linux工具之sar
    利用系统缓存优化程序的运行效率
    Elasticsearch单机部署
  • 原文地址:https://www.cnblogs.com/princeness/p/11664881.html
Copyright © 2020-2023  润新知