# Heading
jsonp
window.postMessage
document.domain
window.name
CORS
# jsonp
JSONP 原理是加载一个 script,并执行一段回调 JS ,因为加载 JS 不需要遵循同源策略。使用这种技术服务器会接受回调函数名作为请求参数,并将JSON数据填充进回调函数中去。 但由此也带来了JSONP的一些问题:
- 无法发送特定的头部
- 只能是 GET 请求
- 无法发送 body
# window.postMessage
postMessage是HTML5新增在window对象上的方法,目的是为了解决在父子页面上通信的问题。 postMessage方法接受两个参数:
message: 要传递的对象,只支持字符串信息,因此如果需要发送对象,可以使用JSON.stringify和JSON.parse做处理
targetOrigin: 目标域,需要注意的是
协议,端口和主机名
必须与要发送的消息的窗口一致。如果不想限定域,可以使用通配符“*”,但是从安全上考虑,不推荐这样做。通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串""(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的origin属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer 是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
页面源中监听message事件就能正常获取消息了。其中,MessageEvent对象有三个重要属性:data用于获取数据,source用于获取发送消息的窗口对象,origin用于获取发送消息的源。
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
# document.domain
目前,很多大型网站都会使用多个子域名,而浏览器的同源策略对于它们来说就有点过于严格了。如,来自www.a.com想要获取document.a.com中的数据。只要基础域名相同,便可以通过修改document.domain为基础域名的方式来进行通信,但是需要注意的是协议和端口也必须相同。
# window.name
window.name这个全局属性主要是用来获取和设置窗口名称的,但是通过结合iframe也可以跨域获取数据。我们知道,每个iframe都有包裹它的window对象,而这个window是最外层窗口的子对象。所以window.name属性就可以被共享。
window对象有一个name属性,该属性有一个特征:即在一个窗口的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每一个页面对window.name都有读写的权限,window.name是持久的存在于一个窗口载入的所有页面中的,并不会因为新的页面的载入而被重置。
源页面新建iframe框架,重定向到目标页面,然后使用iframe.contentWindow.name获取数据。
数据页面中要存放的数据需要存储在window.name 属性中
**var data={msg:"hello world"};
window.name=JSON.stringify(data);//name属性只支持字符串,支持最大2MB的数据
# CORS
CORS的核心思想是通过一系列新增的HTTP头信息来实现服务器和客户端之间的通信。所以,要支持CORS,服务端都需要做好相应的配置,这样,在保证安全性的同时也更方便了前端的开发。
在服务器端返回允许跨域访问的头。