同源策略
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>
网友评论