所谓“同域限制”是指,出于安全考虑,浏览器只容许脚本与一样协议、一样域名、一样端口的地址进行通讯。javascript
浏览器限制不一样窗口(包括iFrame窗口)之间的通讯,除非两个窗口装载的是同一个域名下的网页。window.postMessage方法就是为了解决这个问题而特定的API,可让不一样域名的窗口互相通讯。html
postMessage方法的格式以下:java
targetWindow.postMessage(message, targetURL[, transferObject]);
上面代码的targetWindow是指向目标窗口的变量,message是要发送的消息,targetURL是指定目标窗口的网址,不符合该网址就不发送信息,transferObject则是跟随信息一块儿发送的Transferable对象。windows
假定当前网页弹出一个新窗口。浏览器
var popup = window.open(...popup details ...);
而后在当前网页上监听message事件。安全
window.addEventListener('message', receiveMessage, false); function receiveMessage(e) { if (e.origin != 'http://example.org') { return; } console.log(e.data); }
上面的代码指定message事件的回调函数是receiveMessage,一旦收到其余窗口发来的信息,receiveMessage函数就会被调用。receiveMessage函数接受一个event事件对象做为参数,该参数里的origin属性表示信息的来源网址,若是该网址不符合要求,就马上返回。event.data属性则包含了实际发送过来的信息。app
event对象的属性除了origin和data,还有一个source属性,指向向当前网页发送信息的窗口对象。函数
接着,在当前网页上使用postMessage方法对新窗口发送信息。post
popup.postMessage('hello world!', 'http://example.org');
上面代码的postMessage方法的第一个参数是实际发送的信息,第二个参数是指定发送对象的域名必须是http://example.org。若是对方窗口不是这个域名,信息不会发送出去。spa
最后,在popup窗口中部署下面的代码。
//popup 窗口 function receiveMessage(event) { event.source.postMessage('Nice to see you!', '*'); } window.addEvengtListener('message', receiveMessage, false);
上面代码有几个地方须要注意。首先,receiveMessage函数里面没有过滤信息的来源,任意网址发来的信息都会被处理。其次,postMessage方法中指定的目标窗口的网址是一个星号,表示该信息能够向任意网址发送。一般来讲,这两种作法是不推荐的,由于不够安全,可能会被对方过滤掉。
全部浏览器都支持这个方法,可是IE8和IE9只容许postMessage方法与iFrame窗口通讯,不能与新窗口通讯。IE10容许与新窗口通讯,可是只能使用IE特有的MessageChannel对象。
[1] Mozilla Developer Network, Window.postMessage
[2] Stack Overflow, Is cross-origin postMessage broken in IE10?
[3] ruanyifeng, 同域限制和window.postMessage方法