参考
1.MDN window.postMessage
2.浏览器同源政策及其规避方法
3.跨域资源共享 CORS 详解
1. 什么是同源策略
浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
同源指域名、协议、端口都相同
以http://www.example.com/a.html
为例http://
为协议、www.example.com
为域名,80
为默认端口号;所以像https://www.example.com/b.html
、http://a.example.com/b.html
、 http://www.example.com:90/b.html
与http://www.example.com/a.html
均不同源。
对于当前页面来说页面存放的 JS 文件的域不重要,重要的是加载该 JS 页面所在什么域
2. 什么是跨域?跨域有几种实现形式
3. JSONP 的原理是什么
4. CORS是什么
5. 几种跨域实现方式
- JSONP
- JSONP 是JSON with padding(填充式JSON 或参数式JSON)的简写
- 原理:利用
<script>
标签可以引入不同域下资源的特性;向服务器请求JSON数据,服务器接收请求,将数据放在一个指定名字的回调函数里传回来。如callback({ "name": "Nicholas" });
- JSONP只支持get请求,对于老的浏览器兼容性好
- CORS
- CORS 全称是跨域资源共享(Cross-origin resource sharing),是一种利用 Ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。实现方式很简单,IE8中引入的XDR(XDomainRequest)部分实现了CORS规范
- CORS分为简单请求和复杂请求
- 简单请求
需同时满足请求的方法是post
,get
,head
之一,头信息为以下字段的一个或多个:Accept
,Accept-language
,Content-language
,Last-Event-ID
,Content-Type
为application/x-www-form-urlencoded、multipart/form-data、text/plain
之一。
当你使用 XMLHttpRequest 发送跨域请求时,浏览器会给该请求加一个请求头:Origin,其中包含请求页面的源信息(协议、域名和端口),服务器如果认可这个请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin返回相同的源信息; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。 - 复杂请求
支持开发者使用自定义头部,除了简单请求之外的请求方式、如put
,delete
,以及不同类型的主体内容;浏览器通过以上字段发现这是一个复杂请求后,会先发送一个‘预检’请求,确认服务器可以接收这样的请求,再正式发送请求,预检请求简单示例如下:
- 简单请求
OPTIONS /cors HTTP/1.1 //‘预检’请求使用OPTIONS方法
Origin: http://api.bob.com //请求源
Access-Control-Request-Method: PUT //请求方法
Access-Control-Request-Headers: X-Custom-Header //自定义头信息
服务器会将自己支持的所有请求信息在响应中返回给服务器,之后浏览器会向简单请求一样发送正式请求。
- 降域
- 对于来自同一主域名下的不同子域,通过将每个页面的document.domain设置为相同的值,这些页面就可以互相访问对方包含的JavaScript 对象
- 不能设为URL中不包含的域
- 如
http://a.example.com/a.html
和http://b.example.com/b.html
的同时设置document.domain='example.com'
就可以互相访问了。
- postMessage
-
window.postMessage()
是h5规范中XDM(跨文档消息传送cross-document messaging)的核心 -
otherWindow.postMessage(message, targetOrigin, [transfer])
-
otherwindow
为一个窗口的引用,指向接收信息的窗口,如window.frame[i]
或通过window.open
返回的窗口对象 -
message
为发送的消息 -
targetOrigin
为接收消息的域
-
- 接收到XDM消息时,会触发window的message事件,传递给onmessage处理程序的事件对象包含:
- data:作为postMessage()第一个参数传入的字符串数据
- origin:发送消息文档所在域
- ……
-