浏览器同源策略

ObjectKaz Lv4

同源的概念

对于两个URL,若协议、主机名称、端口相同,则这两个URL就是同源的。

同源策略限制的一些情形

Web页面中的同源策略

两个跨域页面的限制

下面先来考虑几种情况:

  1. 当你使用 window.open 打开一个新页面时,这个函数便会返回新窗口的 window 对象,这个时候就可以控制打开页面的DOM了。

  2. 同样,这个新窗口也可以通过 window.opener 拿到和修改原窗口的DOM信息。

  3. 在页面放置一个 iframe 元素,这时候可以通过 iframe.contentWindow 来拿到和修改框架内页面的DOM信息。

  4. 同样,iframe 内的页面也可以通过 window.parent拿到父窗口的信息。

这看起来方便,但如果打开了一个恶意网站,那么这个恶意网站就有机会读取密码,用户的Cookie 等一些敏感信息了。

因此,如果这涉及到两个不同源的页面,浏览器会限制其对另一个 window 的访问,这样,就避免了如Cookie被盗取等危险的情况。

数据层面中的同源策略

同源策略也限制了不同源的站点读取当前站点的 Cookie、IndexDB、LocalStorage 等数据。

Cookie的作用域

Cookie 可以通过修改其 DomainPath属性,来限制当前Cookie的作用范围。

网络请求中的同源策略

同源策略会限制通过 XMLHttpRequest 等异步方式向不同域发送网络请求。但是链接跳转、表单提交、重定向仍然是不受限制的。

不受同源策略限制的情形

资源的嵌入

安全性和便利性往往是对立的,安全性过强就对于开发者来说就不方便了,比如说使用CDN。

如果页面只是引用了第三方网站(如CDN)的样式,视频/图片等,就不会受到同源策略的限制了。引入视频啥的毕竟不是脚本,不容易出现盗取用户信息的情况。

**对于脚本的引入,也是不受同源策略的限制。**不过,这就可能会有坏人往页面注入一些恶意代码,然后执行,进而盗取信息了。

可以考虑使用内容安全策略 CSP 来限制这一方面的内容

安全的跨域通信

但这也一定程度上阻碍了这两个页面的正常通信,所以浏览器提供了 postMessage 这样的API来进行安全的跨域通信。

此外,例如 close,focus 等API不会读取网页中的隐私信息也是不受限制的。

避开跨域的限制

JSONP

这个特性也可以被用来解决跨域带来的负面影响,一个典型的例子是 JSONP。当需要发起一个请求时,可以带上返回函数的名称,在浏览器中添加一个 script 标签。然后这个请求就返回一个带有函数调用的JS代码,来将请求的数据传递给发起接口的调用者。

但是,JSONP只支持GET请求,且实现较为繁琐。

CORS

跨域资源共享(Cross-origin resource sharing)是为了不同站点下的交互,而设计的一套HTTP请求和响应头。

默认情况下,直接向另一个源发送异步请求(如www.baidu.comwww.github.com)会被浏览器阻止。但是,如果www.github.com增加了一些跨域的响应头,浏览器便不会阻止这个请求。

简单请求和复杂请求

有时候,在CORS策略下,跨域请求之前会发送一次预检的请求(OPTIONS请求方法),而有些请求则不需要。

对于需要发送预检请求的请求,则这个请求称为复杂请求。而不需要发送预检请求的请求则称为简单请求

如果一个请求满足下面的条件,则称为简单请求:

  1. HTTP方法:GET/POST/HEAD
  2. Headers字段:Accept/Accept-Language/Content-Language/Content-Type
  3. Content-Type:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

详细见 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

跨域请求的响应头

对于简单请求,需要在响应中加上;对于复杂请求,则需要在预检请求中加上。

响应头解释
Access-Control-Allow-Origin允许访问该资源的域
Access-Control-Allow-Methods允许访问该资源的方法
Access-Control-Allow-Headers允许访问该资源时添加的头部
Access-Control-Allow-Credentials允许请求带上认证信息,如Cookie、Authorization Headers
Access-Control-Max-Age跨域信息的缓存时间

预检请求的请求头

请求头解释
Access-Control-Request-Method将要请求的方法
Access-Control-Request-Headers复杂请求包含的头部信息

服务器反向代理

通过在即将部署网站的服务器上添加一个代理,就可以使得请求URL属于同源URL了。

  • 标题: 浏览器同源策略
  • 作者: ObjectKaz
  • 创建于: 2022-02-23 14:38:59
  • 更新于: 2022-02-24 07:27:46
  • 链接: https://www.objectkaz.cn/c7c7797cd600.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。