页面间通信方法
- 父页面对于同源的iframe和window.open(URL,name,features,replace)打开的窗口能访问其 DOM。
- 存储在浏览器中的数据,如Cookie,localStorage和IndexedDB,以源进行分割。每个源都拥有自己单独的存储空间,一个源中的Javascript脚本不能对属于其它源的数据进行读写操作。
- postMessage方法可以跨文档通信/通道通信。
- Ajax请求等前后端通信方法。
有些方法有着同源限制,所以主要记录一下跨域问题及解决。
同源
判断同源的条件
- 相同的协议
- 相同的域名(主机)
- 相同的端口号(IE例外)
非同源的限制
- 无法读取 cookie, localStorage, indexDB
- 不能获得不同源的窗口或框架的DOM(可拿到引用但访问内容受限)
- ajax 调用无法正常接收数据
不受同源限制的
- 提交表单
- 由 DOM 发起的网络请求(例如:img, script,CSS 等 DOM 元素加载资源)(能使用元素的src属性发信息,能获取静态资)
跨域通信方法
document.domain
脚本可以将 document.domain 的值设置为其当前域*或其当前域的超级域*。故,若主域名相同时,可通过设置domain解决跨域问题。需要注意的是:浏览器单独保存端口号。对document.domain的任何赋值操作,包括document.domain = document.domain都会以null值覆盖掉原来的端口号。赋值时必须带上端口号,以确保端口号不会为null。(若想共享cookie,也可在 response 里修改 cookie 的 domain 。)
Web Messaging API
message事件
该事件的事件对象 event 有以下5个属性:
- event.data: 接收到的数据
- event.origin: 数据发送方的源
- event.lastEventId: 当前的消息事件的唯一标识符
- event.source: 数据发送方的窗口对象的引用
- event.ports: 发送消息的MessagePort](http://dev.w3.org/html5/postmsg/#messageport)对象
不支持事件冒泡;不能取消;没有默认行为。
postMessage方法
跨文档通信
windowObj.postMessage(message, targetOrigin, [transfer])
windowObj是其他窗口的一个引用,可以是iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是 window.frames等。
参数:message(发送的消息,可以是字符串、结构对象、数据对象、数组等);targetOrigin(接收文档的来源);transfer(常用于通道通信中,是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权)
通过 window.postMessage,也能使不同窗口的 LocalStorage 进行交互。
通道通信
多用于多源之间的通信。通道消息可以使不同浏览上下文中的代码通过端口直接通信。新建一个 MessageChannel 对象 ,实际上就创造了两个相关联的端口(port1,port2) ,一个端口在发送方并保持开放,另一个被传送到接收方(otherwindow/otherworker)的context。同样使用postMessage方法和onmessage事件监听。
本节Refer: https://dev.opera.com/articles/window-postmessage-messagechannel/
window.name
window.name属性可以存储数据(2MB左右),且无跨域限制(window对象没有改变的话,该 window 跳转的网页都能读取 window.name )。需要一个代理页面。如:当页面 A 想要从另一个源获取资源,首先在自己的页面上创建一个隐藏的 iframe B(或开一个窗口),将 B 指向外部资源或服务(例如:otherdomain.com/data.php),B 加载完成之后,把响应的数据附加到 window.name 上。再将页面导航(location 变更)到任何一个与 A 同源的页(即代理页面),这时 A 就可以直接获取到 B 的 name 属性值。缺点是需不断查询数据是否加载完。
使用片段标识符
片段标识符指 url 中 # 之后的部分,即location.hash。 使用片段标识符依托于以下几个关键点:
- 改变 location.hash不会触发页面的刷新的
- 不同源的页面间虽然不能操作 iframe 中的
window和dom,但是可以改变 iframe 的url - window 对象可以监听
hashchange事件
当 A 想要向 B 发送信息时,它可以修改 B 的 hash 值。B 中的函数将轮询自身的 hash 值,找出 A 发送的是什么,然后它可以用同样的方式回复 A。如果 A 想接收这条消息,也需要轮询其本身的 hash 值。
refer: https://www.ibm.com/developerworks/cn/web/wa-crossdomaincomm/
Ajax跨域
CORS
使用自定义的HTTP头部让浏览器与服务器沟通。附加一个Origin头部。服务器也要进行相应设置。
JSONP
动态插入
script标签,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。类似的还有使用图像Ping。实质上是通过DOM请求静态资源,不受同源限制。
More
这篇主要讲的是前端页面的通信,因为涉及跨域问题,所以也简单记录了Ajax的跨域。对于前后端的信息交互,可以参考:前后端数据交互