同源政策
同源
A网页设置的Cookie/localStorage
等,B网页不能打开,除非这两个网页同源
。
- 协议相同
- 域名相同
- 端口相同
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
不同网站之间不会共享Cookie
等信息,比如微博无法获取知乎登录用户的Cookie
。
限制范围
如果不是同源,以下三种行为受到限制:
Cookie
、LocalStorage
和IndexDB
无法读取DOM
无法获得AJAX
请求不能发送
规避同源:一级域名相同,只有二级域名不相同
Cookie
两个网页一级域名
相同,只是二级域名
不同,浏览器允许通过设置document.domain
共享Cookie
。
A网页是http://w1.example.com/a.html
,B网页是http://w2.example.com/b.html
,那么只要设置相同的document.domain
,两个网页就可以共享Cookie
。
以下方法只适用于Cookie
和iframe
窗口:
document.domain = 'example.com';
//A设置cookie
document.cookie = "test1=hello";
//B读取cookie
var allCookie = document.cookie;
规避同源:完全不同源
iframe
如果两个网页不同源,就无法拿到对方的DOM
。典型的例子是iframe窗口
和window.open
方法打开的窗口,它们与父窗口无法通信。
完全不同源的网站,目前有三种方法,可以解决跨域窗口的通信问题
- 片段识别符(fragment identifier)
- window.name
- 跨文档通信API(Cross-document messaging)
片段识别符
window.name
window.postMessage
AJAX
以下三种方法规避限制:
- JSONP
- WebSocket
- CORS
JSONP
网页通过添加一个
<script>
元素,向服务器请求JSON数据
,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
//网页动态插入<script>元素,由它向跨源网址发出请求
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
WebSocket
WebSocket
是一种通信协议,使用ws://(非加密
)和wss://(加密)
作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
CORS
CORS
是一个W3C标准,全称是跨域资源共享
(Cross-origin resource sharing)
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。