用postMesage实现跨域,并解决Failed to execute 'postMessage' on 'DOMWindow'
来源:互联网 发布:三线性优化各向异性 编辑:程序博客网 时间:2024/06/05 08:42
前言
看了HTML5的postMessage,觉得好像挺好玩的,突然想要去尝试下,但是前提就是要有两个不同的源
源 = 规则(http/https)+主机(localhost/其他域名)+端口号,只要有一个不一样,那么两个网页就是不同的源,在浏览器会实现javascript的同源策略,对于不同的源是不能通信的,但是HTML5实现了postMessage标准。
配置两个网页不同源
当时看HTML5的postMessage的时候,我就在想端口号不同就可以实现不同源,那我在我主机开两个内置服务器就好啦。当时我是用aptana写HTML5的,我看见它有一个内置web服务器,端口号是8020,可能8080被我的tomcat占用了吧。然后我就想到我的tomcat服务器的端口号是8080。耶!这样子就解决了设置两个网页不同源啦。
理解HTML5 postMessage原理
理解postMessage实现跨文档消息通信其实不是很难,就是发送方用postMessage给接受方一个消息,然后接收方监听message事件,就是事件驱动,通过messageEvent中的data来获取发送方发送的消息,origin来获取发送方所在的源(可以用来屏蔽掉其他源的网页发来的消息)。
开始编写postMessage代码
说说容易,写起来真的很难。我用iframe标签来模拟不同源的两个页面
主页面
url :http://localhost:8020/measurementWeb/html5.html角色:接收方
<iframe src="http://localhost:8080/boring.html" ></iframe>对应的脚本
window.addEventListener( "message",function(e){alert(e.data);},false);对应的e就是我们上面讲得messageEvent,它是通过参数传递到我们的监听函数的。
iframe页面
url:http://localhost:8080/boring.html角色:发送方
<button id="btn">press</button>对应的脚本
document.getElementById("btn").onclick = function() { //localhost:8020就是发送的url的源 //记住要写top.postMessage或者是parent.message,对于top和parent区别,google一大堆 //千万不要写window.postMessagetop.postMessage("hello", "http://localhost:8020");}
这样子我们的代码就完成了。
有图有真相
主页面:
只要点击iframe 中的按钮,那么在主页面就会弹出hello,因为我们已经在子窗口中用postMessage方法发送到主页面,发送的数据是"hello",不清楚请看iframe标签对于的javascript脚本,而我的主页面监听了message事件,设置了监听函数,弹出来e.data就是iframe发送的数据。
问题Failed to execute 'postMessage' on 'DOMWindow'
到了这里本来应该这篇postMessage入门篇已经结束啦,还要写什么呀?我之前说其实说说很容易,写起来有点难,因为我遇见一个bug,困惑了我很久,就是Failed to execute 'postMessage' on 'DOMWindow'
那为什么会出现这个问题?上面在写iframe的脚本时,我提醒了要用top.postMessage,不要用window.postMessage,其实top就是指向iframe最顶层的窗口,在我们这个例子中,因为主页面只内嵌一个窗口,所以对于子窗口top是等于parent,那我们如果用window.postMessage会出现什么问题呢?就会出现上面那个问题。其实是自己想当然了,对于postMessage语法了解不是很深,所以会导致上面的问题。
window.postMessage MDN
otherWindow.postMessage(message, targetOrigin, [transfer])所以只样子就解决了为什么要用top不用window了,现在发送方是iframe,但是我用的是window就是指iframe的window对象,但是这个不符合postMessage语法,要用到接收方的引用,也就是top.otherWindow: A reference to another window(接收方的引用)
message:Data to be sent to the other window.(要发送到接受方的数据)
targetOrigin:Specifies what the origin of otherWindow must be for the event to be dispatched(接收方的 源,还有必须要有监听message事件)
参考文献
window.postMessageHow do you use window.postMessage across domains?
- 用postMesage实现跨域,并解决Failed to execute 'postMessage' on 'DOMWindow'
- Failed to execute 'texImage2D' on 'WebGLRenderingContext
- maven failed to execute goal on project
- Failed to execute goal on project...
- Failed to execute 'importScripts' on 'WorkerGlobalScope'
- Failed to execute mysql_file_stat on file
- DOMException: Failed to execute 'insertBefore' on 'Node'
- 解决:Failed to execute goal on project aopcore: Could not resolve dependencies for project com.cmos:
- Uncaught SecurityError: Failed to execute 'replaceState' on 'History':解决方案
- postMessage()实现跨域
- Failed to execute aapt
- Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'file:///E:/test
- Failed to execute /linuxrc. Attempting defaults...的解决
- 解决挂载ramdisk时Failed to execute /linuxrc.问题
- 解决Failed to execute goal org.apache.maven.plugins
- 解决Failed to execute goal org.apache.maven.plugins
- 解决Failed to execute goal org.apache.maven.plugins
- 解决Failed to execute goal org.apache.maven.plugins
- (leetcode)Evaluate Reverse Polish Notation
- 编程之美 打酱油 格格取数
- 关于Spring 注解 IOC
- Presentation 需要注意的四个维度
- android文件访问实例
- 用postMesage实现跨域,并解决Failed to execute 'postMessage' on 'DOMWindow'
- java.util.concurrent.Future 类基础
- Struts2 checkbox复选框 传值/取值
- 互联网公司笔试常见陷阱
- html5 内容区域
- 学习笔记_java web——数据源和连接池
- 从Label和TextBox的角度看ViewState
- 开发笔记之20140414
- 开发管理细节,持续更新...