从同源策略到跨域方法

2019-02-16  本文已影响0人  bingshuihe

参考阮一峰老师的文章

同源策略

1.同源策略: 是一种约定,是浏览器最基础的安全策略.web是构建在同源策略基础上的,浏览器不同的域名不能访问对应的cookie。

2.什么是同源: 

          相同的协议;

          相同的域名;

          相同的端口;

3.同源策略的限制:

          Cookie, LocalStorage, IndexDB无法读取;

          DOM无法获得;

          AJAX不能发送请求;

但是表单的提交不受同源策略的限制。


跨域方法

1. 设置document.domain共享 Cookie

域名1: test1.xxx.com;

<scritpt>

document.domain="xxx.com"

document.cookie="test=hello";

</script>

域名2: test2.xxx.com;

<script>

document.domain="xxx.com"

document.cookie;

//这样test1,test2可以共享cookie;

</script>

上述方法只适应与cookie和iframe。并不能读取localStorage和indexDB;

最实用的方法是在服务器端设置

Set-Cookie: key=value; domain=.www.com; path=/;

这样的话,二级域名和三级域名都不用设置就可以访问cookie。

2.jsonp跨域

<script type="text/javascript">

function test(data) {

    //{data:'xxx'}

    //接收data

}

</script>

//在script中带callback参数

<script type="text/javascript" src="www.ssss.com.index.hph?callback=test"></script>

//index.php中写

if(callback){

    return test({data: 'xxx'})

} else {

    return {data: 'xxx'}

}

3.window.postMessage

window.postMessage是无论是否同源,允许窗口通信的html5规范中的API。

父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage方法就可以了。

var popup = window.open('http://bbb.com', 'title');

popup.postMessage('Hello World!', 'http://bbb.com');

postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。

子窗口向父窗口发送消息的写法类似。

window.opener.postMessage('Nice to see you', 'http://aaa.com');

父窗口和子窗口都可以通过message事件,监听对方的消息。 window.addEventListener('message', function(e) { console.log(e.data); },false);

message事件的事件对象event,提供以下三个属性。

event.source:发送消息的窗口

event.origin: 消息发向的网址

event.data: 消息内容下面的例子是,子窗口通过event.source属性引用父窗口,然后发送消息。

window.addEventListener('message', receiveMessage);

function receiveMessage(event) { event.source.postMessage('Nice to see you!', '*'); } event.origin属性可以过滤不是发给本窗口的消息。

window.addEventListener('message', receiveMessage);

function receiveMessage(event) { if (event.origin !== 'http://aaa.com') return; if (event.data === 'Hello World') { event.source.postMessage('Hello', event.origin); } else { console.log(event.data); } }

4.CORS

CORS是跨源资源分享是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

5.window.name

        浏览器窗口有一个window.name属性,这个属性最大的特点是无论是否同源,只要在同一个窗口,前一个页面设置了属性,后一个页面就可以使用。

        这种方法的优点是,window.name容量很大,可以放置非常长的字符串;缺点是必须监听子窗口window.name属性的变化,影响网页性能。

6.片段识别符

片段识别符是指url#后边的标志符。改变片段标志符,页面不会刷新。

父窗口可以把信息,写入子窗口的片段标识符。

var src = originURL + '#' + data; document.getElementById('myIFrame').src = src;

子窗口通过监听hashchange事件得到通知。

window.onhashchange = checkMessage; function checkMessage() { var message = window.location.hash; // ... }

同样的,子窗口也可以改变父窗口的片段标识符。 parent.location.href= target + "#" + hash;

7.WebSocket协议不实行同源策略

       在WebSocket的请求头中有一个origin字段,有了这个字段,服务器可以根据这个字段判断是否允许本次请求服务。

8.其他的如<link> (background),<img>,<iframe>

(1)img跨域

<img src="xxx.jpg" />

实践:测试用户网速

var img = new Image();

var start = Date.now();

img.src = "....";

img.onload = function(args){

    var end = Date.now();

    var t = start - end;

    var v = '1.1 '/ t;

}

(2).iframe跨域

<iframe src="test.xxxx.com"></iframe>

上一篇下一篇

猜你喜欢

热点阅读