最近面试遇到很多问跨域怎么解决什么的问题。于是我将采用问答的形式解读一下跨域的相关问题。
请解释一下同源策略 SOP,为什么要有同源限制?
- 概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议
- 指一段脚本只能读取来自同一来源的窗口和文档的属性
我对浏览器的同源政策的理解是,一个域下的 js 脚本在未经允许的情况下,不能够访问另一个域的内容。这里的同源的指的是两个域的协议、域名、端口号必须相同,否则则不属于同一个域。
| url | 同源 |
|---|---|
| niconico.com(opens new window) | 基准 |
| niconico.com/spirit | o |
| sub.niconico.com/spirit | x |
| niconico.com/spirit | x |
| niconico.com:8080/spirit | x |
同源政策主要限制了三个方面
第一个是当前域下的 js 脚本不能够访问其他域下的 cookie、localStorage 和 indexDB。
第二个是当前域下的 js 脚本不能够操作访问操作其他域下的 DOM。
第三个是当前域下 ajax 无法发送跨域请求。
同源政策的目的
主要是为了保证用户的信息安全,它只是对 js 脚本的一种限制,并不是对浏览器的限制,对于一般的 img、或者script 脚本请求都不会有跨域的限制,这是因为这些操作都不会通过响应结果来进行可能出现安全问题的操作。
其实表面上 SOP 分两种情况:
-
可以正常引用 iframe、图片等各种资源,但是限制对其内容进行操作
-
直接限制 ajax 请求,准确来说是限制操作 ajax 响应结果,这会引起 CSRF
但是,本质上这两条是一样的:总之,对于非同源的资源,浏览器可以“直接使用”,但是程序员和用户不可以对这些数据进行操作,杜绝某些居心不良的行为。这就是现代安全浏览器对用户的保护之一。
- 如果你说 SOP 就是“限制非同源资源的获取”,这不对,最简单的例子是引用图片、css、js 文件等资源的时候就允许跨域。
- 如果你说 SOP 就是“禁止跨域请求”,这也不对,本质上 SOP 并不是禁止跨域请求,而是在请求后拦截了请求的回应。
为什么要有同源限制?
-
我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。
-
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?
很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
-
缺点
- 现在网站的JS都会进行压缩,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge后,这个串就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节