浏览器同源策略

Published: · LastMod: October 06, 2022 · 642 words

浏览器同源策略(Same-origin policy) 🔗

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

同源包括三个部分

  • protocol 协议
  • port 端口 (IE对于不同的port会视为同源)
  • host 主机名

image.png

https://domain-a.com:80/hannah-lin 为例

1
2
3
4
5
http://domain-a.com  不同源scheme 不同
https://domain-a.com/mike  同源
https://news.domain-a.com  不同源domain 不同
https://domain-a.com:81  不同源port 不同
https://domain-b.com  不同源domain 不同

非同源的行为限制

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求不能发送。

两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置相同的document.domain共享 Cookie。

1
document.domain = 'example.com';

这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法,规避同源政策

服务器在设置cookie时也可以设置一级域名

1
Set-Cookie: key=value; domain=.exaple.com;

二级域名和三级域名不需要设置,都可以读取这个Cookie

window.postMessage 🔗

html5中对于夸文档通信,新增了一个postMessage方法

父窗口 -> 子窗口

1
2
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

子窗口 -> 父窗口

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

各自页面中也都可以通过监听message方法获取数据

1
2
3
window.addEventListener('message', function(e) {
  console.log(e.data);
},false);

JSONP 🔗

通过动态添加script元素, 服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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://(加密)作为协议前缀。

WebSocket通过请求头中的Origin字段判断是否允许请求