什么是同源策略?
同源是浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略
同源三大要素:,就是必须协议、域名、端口
都一致的,才叫做同源
- 相同协议:如都是http或者https
- 相同域名:是用来定位网站的独一无二的名字
http://jirengu.com/a
和http://jirengu.com/b
或者www.baidu.com
和www.baidu.cn
- 相同端口:如都是80端口,或者8080端口
看一些同源例子:
http://jirengu.com/a/b.js
和http://jirengu.com/index.php
(同源)
不同源的例子:
http://jirengu.com/main.js
和https://jirengu.com/a.php
(协议不同)
http://jirengu.com/main.js
和http://bbs.jirengu.com/a.php
(域名不同,域名必须完全相同才可以)
http://jiengu.com/main.js
和 http://jirengu.com:8080/a.php
(端口不同,第一个是80)
需要注意的是: 对于当前页面来说页面存放的 JS 文件的域不重要,重要的是加载该 JS 页面所在什么域
同源策略的目的是什么:
- 为了保证用户信息的安全,防止恶意网站窃取数据
- Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
- 所以同源策略非常重要,不然cookie可以共享,互联网没有安全可言。
限制范围
- 非同源:
Cookie(window.domain)
-
DOM无法获取(iframe和window.open打开的窗口)
(window.domain)(window.postMessage) -
AJAX
请求不能发送
如何规避这些限制呢??
规避限制一: cookie
- cookie是服务器写入浏览器的一段信息,只有同源的可以共享,网站要求用户登入自己的账户,登入后,认证接口就会下发给浏览器一个cookie,通过
document.domain
Set-Cookie: key=value; domain=.example.com; path=/
完成了cookie的植入,通过这种策略就完成了网站的统一认证登入,这个在cookie中就会有一个相对比较重要的cookie参数
规避限制二: iframe
如果两个网页不同源,就无法拿到对方的DOM。
解决方法:
片段识别符(fragment identifier)
window.name
跨文档通信API(Cross-document messaging)
限制规避三: Ajax
- JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。 - WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
- CORS这个是现在用到比较广的一种方式,全称是”跨域资源共享”。
后面重点讲解ajax的不同源解决方案
什么是跨域?跨域有几种实现形式
先了解一下什么是跨域
跨域就是允许不同域的接口进行交互,说白点就是post、get的url不是你当前的网站,域名不同。
- 跨域的几种方式:
- JSONP
- CORS
- 降域
- postMessage
JSONP 的原理是什么
- 自动跨域的前提是服务端愿意提供接口给你用,
- 利用了
javascript
可以加载一个东西,不受同源策略的限制,相当于可以加载任意的东西作为js
来执行,但需要后端来支持 - 数据来了以后,我们自己写好了一个函数来操作这些数据,最后在src后面加上最后加个参数
callback=_fun(函数名)
专业总结就是
- 定义数据处理函数_fun
- 创建script标签,src的地址执行后端接口,最后加个参数callback=_fun
- 服务端在收到请求后,解析参数,计算返还数据,输出 fun(data) 字符串。
- fun(data)会放到script标签做为js执行。此时会调用fun函数,将data做为参数。
CORS是什么
-
CORS 全称是跨域资源共享(Cross-Origin Resource Sharing)
,是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式很简单,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。
- 需要修改
hosts
文件
降域
降域其实是吧域名降一个等级
document.domain
postMessage
-
postMessage
的原理是会向另一个地方发送信息,另一个地方通常是iframe,或者是由当前页面弹出的窗口。参数是:信息以及表示接受消息方的来自哪个域的字符串,如果给定*便是不限定接受者的域。
所以在一个html中嵌入另一个html文件的iframe,并且互相发送postMessage并响应在input框以此来观察效果。