🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
我们知道浏览器的主要工作是把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**,只不过这个方法需要服务器的配合了”