同源策略
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以 xyz.com 下的 js 脚本采用 ajax 读取 abc.com 里面的文件数据是会被拒绝的。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
所谓同源是指:域名、协议、端口相同。
网址 | 结果 | 原因 |
---|---|---|
https://yuwangi.github.io | 成功 | 域名、协议、端口均相同 |
http://yuwangi.github.io | 失败 | 协议不同 |
https://yuwangi.github.io:9001 | 失败 | 端口不同 |
https://smwang.github.io | 失败 | 域名不同 |
为什么要有跨域限制
因为存在浏览器同源策略,所以才会有跨域问题。那么浏览器是出于何种原因会有跨域的限制呢。其实不难想到,跨域限制主要的目的就是为了用户的上网安全。
如果浏览器没有同源策略,会存在什么样的安全问题呢。下面从 DOM
同源策略和 XMLHttpRequest
同源策略来举例说明:
如果没有 DOM
同源策略,也就是说不同域的 iframe
之间可以相互访问,那么黑客可以这样进行攻击:
做一个假网站,里面用 iframe
嵌套一个银行网站 http://mybank.com
把 iframe
宽高啥的调整到页面全部,这样用户进来除了域名,别的部分和银行的网站没有任何差别。
这时如果用户输入账号密码,我们的主网站可以跨域访问到 http://mybank.com
的 dom
节点,就可以拿到用户的账户密码了。
如果 XMLHttpRequest
同源策略,那么黑客可以进行 CSRF
(跨站请求伪造) 攻击:
用户登录了自己的银行页面 http://mybank.com,http://mybank.com
向用户的 cookie
中添加用户标识。
用户浏览了恶意页面 http://evil.com
,执行了页面中的恶意 AJAX
请求代码。http://evil.com
向 http://mybank.com
发起 AJAX HTTP
请求,请求会默认把 http://mybank.com
对应 cookie
也同时发送过去。
银行页面从发送的 cookie
中提取用户标识,验证用户无误,response
中返回请求数据。此时数据就泄露了。
而且由于 Ajax
在后台执行,用户无法感知这一过程。
因此,有了浏览器同源策略,我们才能更安全的上网。
跨域解决方案
- jsonp
- cors
- postMessage
- document.domain
- window.name
- location.hash
- http-proxy
- nginx
- websocket
jsonp
1 | //此处直接手写一个jsonp |
cors
1 | //index.html |
1 | //server.js |
1 | //server2.js |
postMessage
1 | //a.html |
1 | //b.html |
1 | // a server.js |
1 | // b server.js |
document.domain
对于主域名相同,且协议,端口一致,而子域名不同的情况,可以使用 document.domain 来跨域。
1 | //一级域名、二级域名 |
window.name
1 | //a.html |
1 | //b.html |
1 | //c.html |
1 | // server a |
1 | // server b |
location.hash
1 | //a.html |
1 | //b.html |
1 | //c.html |
1 | // a server.js |
1 | // b server.js |
http-proxy
类似于 webpack 转发
1 | devServer: { |
nginx
首先需要先下载 nginx, http://nginx.org/en/download.html
1 | //配置nginx |
1 | //index.html |
1 | //server.js |
websocket
1 | <!DOCTYPE html> |
1 | //server.js |