同源策略属于web安全中的客户端安全,是针对浏览器的前端安全策略,一起来学习吧
![]()
目录
同源策略
什么是同源策略
限制浏览器从同一个源加载的脚本或文档如何与来自另一个源的资源进行交互,这是一个用于隔离潜在恶意文件的重要安全机制
同源策略的判定
{protocol, host, port} 完全相同时,符合同源策略,同源页面之间可以相互访问 (有一个特殊的存在是ie浏览器,只需要protocol和host相同就会判定为满足同源策略)

同源策略本身并不复杂,但是场景很多,再加之浏览器对安全的理解不一致,导致同源策略“乱象丛生”
同源策略的典型场景
1. DOM的同源策略
DOM:文档对象模型(Document Object Model,简称DOM),可以理解为前端页面中的各种标签,比如:<href> <body> <title>
- <script>,<img>,<iframe>,<link>等带有src属性的标签,不受同源策略的约束,可以从不同的域加载和执行资源,且<script>引入的外部js文件的源为当前页面。(这一点也叫作同源策略的非绝对性)

- javascript不能随意跨域操作其他页面的DOM
- JavaScript不能获取<script>,<img>,<iframe>,<link>跨域请求得到的内容,只能在浏览器解析后获取必要的,公共的信息

- <iframe>,父子页面交互受同源策略约束
2. XMLHttpRequest的同源策略
XMLHttpRequest是Ajax中的一个对象,在这一小节中讨论的XMLHttpRequest的同源策略可以理解为Ajax的同源策略
XMLHttpRequest严格受同源策略约束,不能随意跨域请求(也就是在上图的例子中x.open中的url必须与当前为同源才行)。值得注意的是,“不能随意跨域请求”具体指的是,对于不同源的域Ajax是可以请求成功,但是浏览器会阻止脚本返回
3. Web Storage的同源策略
Web Storage是为了克服cookie的一些限制而存在的,当数据需要被严格控制在客户端上时,无须持续地将数据发回服务器,这时候便可以存储在web storage 中,他有两种实现方式:localstorage和sessionstorage
- localstorage:实现与站点源的持续连接,关闭浏览器后仍然有效
- sessionstorage: 绑定当前的浏览器窗口,提供临时的缓存机制,浏览器会话结束之后清理
webstorage 的同源策略指的是,其中保存的信息只能在与当前站点同源的页面中读取
4. 脚本型URL的同源策略

javascript:URL 只能跳转到同源界面(跳转到非同源页面是非常危险的行为,比如XSS攻击)
跨域通信
在某些应用场景中,开发者需要访问不同源的页面,因此需要有一些跨域通信的方法,下面一共会介绍六种
- Server Proxy
- document. domain
- JSONP
- window.name
- CORS
- window.postMessage
其中后两种是HTML原生的方法
1. Server Proxy
同源策略的作用对象时浏览器,所以开发者可以利用服务器来实现跨域通信。

客户端先将请求发送给本域服务器,本域服务器再请求域外服务器,最后依次返回给浏览器,实现跨域访问,缺点是会增加服务器的压力。
2. document. domain
通过在<script>标签中设置document.domain可以实现跨域通信
举例:在父页面father.demo.com中嵌入child.demo.com的iframe子页面
方法: 在两个页面中分别设置document.domain=“demo.com”,可以理解为两个页面有着共同的祖先,由此实现了跨域通信。
限制:使用这个方法时,父子页面的协议号和端口号仍然要相同。
3. JSONP
JSONP:JSON with Padding,在JavaScript返回数据中填充 JSON数据,即 “数据作为JS代码传递”
在上文中有提到<script>标签是不会受到同源策略新限制的,JSONP就是巧妙利用了这一点,将数据作为js代码传递。
4. window.name
window对象的name属性:
全局变量:在窗口(window)的生命周期内,窗口重定向后载入的页面共享window.name。
可读可写:每个页面对window.name可读可写。
持久存储:持久存在,不因新页面的载入而重置。
容量较大:M级别的存储空间。

5. CORS
- 浏览器在发出AJAX请求时,在请求头里声明当前页面的源:Origin: http://server.net/app.htm
- remote.net在响应头中,做如下“跨域授权声明”:header(“Access-Control-Allow-Origin: http://server.net")
- 经过remote.net明确地授权server.net域后,server.net可以读取其返回的数据
6. window.postMessage
window.postMessage是HTML5的新特性,允许不同源的脚本采用异步方式进行有限的通信,实现 跨文档、多窗口、跨域消息传递。
跨域是把双刃剑,开发者的跨域方法也是攻击者绕过同源策略的方法