# 同源策略
# 什么是同源
源(origin)是指协议、域名和端口号。若地址里面的协议、域名和端口号均相同则属于同源。三者有一个不相同则代表着不同源
相对于http://www.uek.com/index.html
做同源检测:
地址 | 结果 |
---|---|
http://www.uek.com/test/a.html | 同源 |
https://www.uek.com/index.html | 协议不同 |
http://www.uekedu.com/index.html | 主机名不同 |
http://www.uek.com:8080/index.html | 端口号不同 |
# IE 例外
- 两个相互之间高度互信的域名,不遵守同源策略的限制。
- IE 未将端口号加入到同源策略的组成部分之中
# 同源策略
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。
# 跨域
# 跨域限制的必要性
上面提到浏览器的同源策略是为了安全。跨域主要存在两方面安全问题
- DOM 同源策略
我们用一个iframe把银行的网站嵌套在我们的网页上,这样的话,我们的网站和银行的网站除了域名没有其他的区别,如果没有同源策略,用户操作网页,我们就可以通过我们自己的网站跨域来访问银行的dom节点,从而拿到用户的信息。 - XMLHttpRequest 同源策略
用户访问银行的网站,银行在用户的客户端中cookie中添加标识。用户再访问恶意网站,如果没有同源策略,恶意网站就会向银行网站发送恶意的ajax请求,请求会把银行给用户cookie中添加的标识发送过去,银行网站识别到正确的cookie返回请求数据,这样数据就会泄漏
# 跨域问题的解决办法
# jsonp(与json并没有什么关系)
在a.com的html页面里创建一个回调函数fun,动态添加<script>
元素,向服务器发送请求,请求地址后面加上查询字符串,通过callback参数指定回调函数的名字。请求地址为http://b.com/main.js?callback=fun
。在main.js中调用这个回调函数fun,并且以JSON数据形式作为参数传递,在a.com通过调用fun中接收参数。
利用script标签没有跨域限制的特点
# 缺点
- 只能使用GET请求
- 不能很好的发现错误,并进行处理。
# 服务器代理
服务器端不存在跨域的问题,所以可以用服务器代理的方式来解决跨域问题。
让自己的服务器去访问另一个服务器,然后再把数据从我们自己的服务器上返回到页面。
A客户端(浏览器) ==> A服务器 ==> B服务器 ==> A客户端(浏览器)
# CORS 的实现
CORS(跨源资源共享)是一个系统,由传输HTTP标头组成,用于确定浏览器是否阻止前端JavaScript代码访问跨源请求的响应。
Access-Control-Allow-Origin: http://www.xxx.com //允许从http://www.xxx.com源请求代码来访问资源。 *代表允许所有的
Access-Control-Allow-Methods:PUT,POST,GET,DELETE,OPTIONS //允许哪些请求方法
Access-Control-Allow-Headers:<header-name> [,<header-name> ] * //请求需要具有的标头
# window.name+iframe
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
在我们的当前页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取数据页面的数据,并把数据存放到window.name上,然后我们的当前页面再去得到iframe获取到的数据。
# window.postMessage(message,targetOrigin)
html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
调用postMessage方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * 。
需要接收消息的window对象,可是通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。
← ajax的简介和使用 Fetch →