同源策略是浏览器安全的基石,它限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互,本文主要介绍同源策略的各个方面。

概述

1995年,同源策略由Netscape公司引入浏览器,目前所有的浏览器都实行这个策略。

定义

同源指的是一下相同:

  • 协议相同:同为http或https
  • 域名相同
  • 端口相同

约束

  • 允许跨域写操作(Cross-origin writes)。例如链接,重定向以及表单提交。特定少数的HTTP请求需要添加preflight
  • 允许跨域资源嵌入(Cross-origin embedding)。
  • 不允许跨域读操作(Cross-origin reads)。

以下是可能嵌入跨源的资源的一些示例:

  • <script src="..."></script> 标签嵌入跨域脚本
  • <link rel="stylesheet" href="..."> 标签嵌入CSS
  • <img>嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,…
  • <video><audio>嵌入多媒体资源
  • <object>, <embed>[<applet>](https://developer.mozilla.org/zh-CN/docs/HTML/Element/applet) 的插件
  • [@font-face](https://developer.mozilla.org/zh-CN/docs/CSS/@font-face) 引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)
  • <frame>[<iframe>](https://developer.mozilla.org/zh-CN/docs/HTML/Element/iframe) 载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。

跨源数据存储访问

不同源,以下行为会收到限制:

  • Cookie,localStorage, IndexedDB无法读取
  • DOM无法获得
  • Ajax请求发送后被浏览器拦截(并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了)

注:不管使用哪个协议(HTTP/HTTPS)或端口号,浏览器都允许给定的域以及其任何子域名(sub-domains) 访问 cookie。设置 cookie 时,你可以使用Domain,Path,Secure,和Http-Only标记来限定其访问性。

跨源脚本API访问

Javascript的APIs中,如 iframe.contentWindow, window.parent, window.openwindow.opener 允许文档间直接相互引用。当两个文档的源不同时,这些引用方式将对 WindowLocation对象的访问添加限制。

Window

允许以下对 Window 属性的跨源访问:

方法
window.blur
window.close
window.focus
window.postMessage
属性
window.closed 只读.
window.frames 只读.
window.length 只读.
window.location 读/写.
window.opener 只读.
window.parent 只读.
window.self 只读.
window.top 只读.
window.window

Location

允许以下对 Location 属性的跨源访问:

方法
location.replace
属性
URLUtils.href 只写.

如何允许跨源访问

参考整理的另一篇文章 跨域方式

参考

https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html