HTML5 postMessage和跨域通信
来源:互联网 发布:android 启动优化 编辑:程序博客网 时间:2024/05/16 01:04
HTML5 postMessage和跨域通信
http://iknowledge.wikispaces.com/HTML5+postMessage%E5%92%8C%E8%B7%A8%E5%9F%9F%E9%80%9A%E4%BF%A1
HTML5 postMessage和跨域通信
浏览器的同源策略
Jesse Ruderman对于同源策略的定义为:“同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性”[1] 。从安全性的角度来说,同源策略认为任何来自其他站点动态装载的内容,其安全性都是不可知的,所以对于浏览器来说,在要求动态内容时,只应该读取同源的HTTP应答和Cookies,而不能读取不同源的内容[2][3] 。如果两个页面拥有相同的源,它们的协议、端口和主机名都相同,那么可以认为这两个页面是同源的,可以动态的读取对方的信息。
- 举个例子来说明同源问题:[4]
- 假设浏览器当前访问的页面是: http://www.google.com/image/logo.html
- + 动态读取: http://www.google.com/image/other.html
- # 同一域名,不同文件,可以读取
- + 动态读取: http://www.google.com/style/style.html, 可以执行
- # 同一域名,不同文件夹,可以读取
- + 动态读取: https://www.google.com/image/logo.html, 不可以执行
- # 同一域名,不同协议,不可以读取
- + 动态读取: http://www.google.com:5656/image/logo.html,不可以执行
- # 同一域名,不同端口,不可以读取
- + 动态读取: http://www.baidu.com/image/logo.html,不可以执行
- # 不同域名,不可以读取
- + 动态读取: http://80.12.122.24/logo.html,不可以执行
- # 域名与域名对应ip,不可以读取
- + 动态读取:http://video.google.com/logo.html,不可以执行
- # 主域相同,子域不同,不可以读取
- + 动态读取:http://google.com/logo.html,不可以执行
- # 同一域名,不同二级域名,不可以访问
跨域通信
如果WebApp需要从第三方的服务器获取数据,该如何避免同源策略的限制呢?
已经存在多种方案,客服同源策略的限制,他们包括:
+ 通过iframe实现跨域通信[5]
+ 通过JSONP实现跨域通信[6]
+ 通过设置Ajax通信代理
HTML5 postMessage() API
postMessage()是HTML5为了解决现存的跨域问题引入的一个新的API。同源策略的前提是假定任何来自其他站点动态装载的内容,其安全性都是不可知的。postMessage将安全问题的检查抛给了使用者本身,在W3C的官方文档中提到,用户应该在使用前自行确认跨域安全[7] 。API:/* * @param message: 需要发送的信息 * @param targetOrigin: 希望发送到的域名 ('*'代表所有的域,'/'代表只发送给同域目标) */window.postMessage(message,targetOrigin [, transfer])
同时在W3C的文档中提到,为了保证postMessage()发送的信息能够被接受到,那么接收端receive message listener的代码应该首先保证被加载和运行。
Example & Tutorial
查看了现在网络上流传的例子,一般设计针对两种usecase:
- 1. 一个页面里面加载了两个iframe,一个iframe向另一个发送信息
- +发送端代码:
setTimeout(function(){ window.parent.frames[1].postMessage('Send message: [Message]','*'); },1000);
- +接受端代码:
var onMessageReceived = function(e){ var msg = e.data; alert('Received message: '+msg); } if (typeof window.addEventListener != 'undefined') { window.addEventListener('message', onMessageReceived, false); }else if (typeof window.attachEvent != 'undefined') { window.attachEvent('onmessage', onMessageReceived); };
- 这里使用了setTimeout延迟1秒是为了保证接收端listener能够首先工作起来。
- [ Example (已经对js代码做了封装的例子) ]
- [ Example (未做封装,推荐学习使用) ]
- 2. 一个页面打开一个新的页面,当前页面将信息传递给新的页面
- 对于这个Usecase来说,具体传送接受的代码没有任何变化,变化的是postMessage的对象,具体请查看Example
- [ Example ]
Reference
- ^ [JavaScript的同源策略 ]
- ^ [浏览器同源策略解释 ]
- ^ [同源策略 ]
- ^ [利用HTML5的window.postMessage实现跨域通信 ]
- ^ [通过iframe实现跨域通信 ]
- ^ [使用JSONP实现跨域通信 ]
- ^ [W3C postmsg API ]
- HTML5 postMessage和跨域通信
- HTML5之postMessage和setEventListener实现<iframe>跨域通信
- iframe跨域通信--html5.postmessage
- html5跨域通信之postMessage
- 利用HTML5的window.postMessage实现跨域通信
- HTML5 postMessage 消息传输与 POST 跨域通信
- HTML5 postMessage 消息传输与 POST 跨域通信
- 利用HTML5的window.postMessage实现跨域通信
- HTML5-postMessage实现跨域
- html5 postMessage解决跨域和跨窗口消息传递
- html5 postMessage跨域通信 1.解决页面与嵌套的iframe消息传递
- HTML5 postMessage 跨域交换数据
- HTML5 postMessage 跨域窗口信息传递
- 使用window.postMessage实现跨域通信
- 用postMessage实现跨域通信
- 使用window.postMessage实现跨域通信
- window.postMessage实现跨域通信
- 使用html5 postMessage和window.name实现多浏览器跨域
- g++编译优化指南
- 实现自己的string
- vs2010 创建dll
- ORA-12547经典错误处理
- 第八周任务三:实现分数类中的运算符重载
- HTML5 postMessage和跨域通信
- zoj 3212
- 问题杂集
- 分数类中的运算符重载(第八周任务三)
- 关于计算机如何做加法
- Shell脚本语法 条件测试:test
- manifest导致XP SP2崩溃问题跟踪说明
- 聊斋志异的夜叉国很有时代色彩
- 炮兵阵地(acm.pku1185)解法