资讯专栏INFORMATION COLUMN

JS跨域

whataa / 2556人阅读

摘要:跨域概述两个不同域互相请求,称为跨域,是由浏览器同源策略限制的一类请求场景。同源策略限制以下几种行为和无法读取无法获得请求不能发送目前主流的用于解决跨域问题的方法跨域缺点这种方法只适用于和窗口,和无法通过这种方法。

跨域概述

两个不同域互相请求,称为跨域,是由浏览器同源策略限制的一类请求场景。

--> 同源策略/SOP(Same origin policy)是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同。

同源策略限制以下几种行为:
1.) Cookie、LocalStorage 和 IndexDB 无法读取

2.) DOM无法获得

3.) AJAX 请求不能发送

目前主流的用于解决跨域问题的方法:

iframe跨域 document.domain+iframe

缺点:这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法。

实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

1.)父窗口:(http://www.domain.com/a.html)


2.)子窗口:(http://child.domain.com/b.html)

-->iframe是什么?iframe 元素会创建包含另外一个文档的内联框架(即行内框架)

postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:

a.) 页面和其打开的新窗口的数据传递

b.) 多窗口之间消息传递

c.) 页面与嵌套的iframe消息传递

d.) 上面三个场景的跨域数据传递

用法:postMessage(data,origin)方法接受两个参数

data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。

origin: 协议+主机+端口号,也可以设置为*,表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

1.)a.html:(http://www.domain1.com/a.html)


2.)b.html:(http://www.domain2.com/b.html)

window.name+iframe

window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

1.)a.html:(http://www.domain1.com/a.html)

var proxy = function(url, callback) {
    var state = 0;
    var iframe = document.createElement("iframe");

    // 加载跨域页面
    iframe.src = url;

    // onload事件会触发2次,第1次加载跨域页,并留存数据于window.name
    iframe.onload = function() {
        if (state === 1) {
            // 第2次onload(同域proxy页)成功后,读取同域window.name中数据
            callback(iframe.contentWindow.name);
            destoryFrame();

        } else if (state === 0) {
            // 第1次onload(跨域页)成功后,切换到同域代理页面
            iframe.contentWindow.location = "http://www.domain1.com/proxy.html";
            state = 1;
        }
    };

    document.body.appendChild(iframe);

    // 获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)
    function destoryFrame() {
        iframe.contentWindow.document.write("");
        iframe.contentWindow.close();
        document.body.removeChild(iframe);
    }
};

// 请求跨域b页面数据
proxy("http://www.domain2.com/b.html", function(data){
    alert(data);
});

2.)proxy.html:(http://www.domain1.com/proxy....
中间代理页,与a.html同域,内容为空即可。

3.)b.html:(http://www.domain2.com/b.html)

总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

AJAX跨域 Vue ProxyTable

本质是创建本地服务器,由本地服务器请求跨域服务器上的数据,服务器之间没有同源限制,

Access-Control-Allow-Origin参数设置

在被请求的文件中添加一个header(IE10以下不支持)

jsonp方法

缺点:只能实现get一种请求。
优点:简单适用,老式浏览器全部支持,服务器改造非常小。

原理:网页通过添加一个

阅读需要支付1元查看
<