我们知道浏览器的主要工作是把HTML、JavaScript等文件从服务器端取下来,然后解析、渲染,展示给人类。
同时浏览器还需要保存cookie,网站会把cookie发给浏览器,等到访问同一个网站的时候,会把cookie发过去 。这个Cookie的作用是用来证明用户已经与服务器交互过了,更重要的是证明已经登录过系统了。
JavaScript的主要作用是对DOM树修改,已经利用AJAX访问服务器端
但是安全的问题还没有解决。
## 跨域访问
有一天,用户登录了icbc网站,网站回复了一个Cookie ,证明用户登录过。
但是用户忘了退出,又登录了一个钓鱼网站。
钓鱼网站居然想访问icbc的Cookie。
按照道理来说Cookie不能随便给别人,因为这样的话,黑客不用登录就可以冒充用户在icbc上做操作了。
## iframe
现在浏览器已经很小心,不会把别的网站的cookie发给JavaScript了。
但是钓鱼网站改变了策略,它用iframe放置了一个淘宝的登录页面
用户一不小心输入了自己的用户名和密码。这样的用户名和密码就被提交到了钓鱼网站中。
![](http://p8a6vmhkm.bkt.clouddn.com/img/20181029151043.png?imageslim)
## 同源
虽然浏览器控制不了人类的行为,但是可以让浏览器增加安全性。
于是,所有浏览器增加了一条铁规:
**除非两个网页是来自于统一源头,否则不允许一个网页的JavaScript访问另一个网页的内容,比如Cookie,DOM等**
也就是如果两个网页不同源,就被隔离了。
那什么叫同一个**源头**?
也就是说`{protocol , host , port}`必须一样。
比如说有这么一个网页: http://www.store.com/product/page.html, 下面的表格列出了各种不同情况。”
![](http://p8a6vmhkm.bkt.clouddn.com/img/20181029151521.png?imageslim)
但是问题又来了。
比如说http://www.store.com/ ,这个页面有一段装载的jquery.js的代码:
```
<script src="//static.store.com/jquery.js >
```
这个 jquery.js 是来自于不同的源(**static**.store.com), 难道他就没法操作 www.store.com 页面的内容了吗? 如果不能操作,这个 jquery.js 就没有任何用处了。
所以可以开个口子,对于使用使用 < script src='xxxxx'> 加载的 JavaScript,我们认为它的源属于 www.store.com, 而不属于 static.store.com,这样就可以操作 www.store.com 的页面了
其实这种 “嵌入式” 的跨域加载资源的方式还有 <img>,<link> 等,相当于浏览器发起了一次 GET 请求,取到相关资源,然后放到本地而已。
## 分布式
随着网络流量增加,大部分系统都拆分成分布式的,每个系统都有子域名,像 login.store.com, payment.store.com ,虽然二级域名不同,但是他们属于一个大的系统,但是由于同源策略的铁规,cookie不能在每个系统之间共享。
那么只能再开一个口子,如果两个网页的一级域名是相同的,他们可以共享 cookie, 不过 cookie 的 domain 一定要设置为那个一级域名才可以,例如:`document.cookie = 'test=true;path=/;domain=store.com'`
## AJAX
我们知道javaScript可以创建一个XMLHttpRequest对象去异步访问服务器端提供的服务,做到局部刷新页面。
但是这个 XMLHttpRequest 对象只能访问源服务器(如 book.com),不能访问其他服务器 (如 beauty.com)?
![](http://p8a6vmhkm.bkt.clouddn.com/img/20181029152331.png?imageslim)
那怎么办?
可以通过**服务器中转**
可以通过服务器端中转啊,例如你是来自 book.com 的, 现在想访问 movie.com,那可以让那个 book.com 把请求转发给 movie.com ,这就是代理
![](http://p8a6vmhkm.bkt.clouddn.com/img/20181029152600.png?imageslim)
但是如果浏览器要访问多个不同源的系统,要是都通过 book.com 中转,该多麻烦!”
既然服务器(domain)之间是互信的,那一个服务器 (domain) 可以设置一个白名单,里边列出它允许哪些服务器 (domain) 的 AJAX 请求。
假设 movie.com 的白名单中有 book.com, 那当属于 book.com 的 JavaScript 试图访问 movie.com 的时候,浏览器做点手脚,悄悄地把当前的源 (book.com) 发过去,询问下 movie.com, 看看他是否允许浏览器访问,如何允许,就继续访问,否则就报错!
![](http://p8a6vmhkm.bkt.clouddn.com/img/20181029152748.png?imageslim)
这样以来,那些黑客就没有办法假冒用户向这些互信的服务器发送请求了, 我把这个方法叫做 Cross Origin Resource Sharing,简称** CORS**,只不过这个方法需要服务器的配合了”