这两个脚本实例可以使用postMessage()
相互通信。关于:
这将需要同步的实例,所以例如有一个iframe只能在网页完成后执行其任务,反之亦然。
这正是this, stunningly brilliant, answer中显示的内容。 ;)
但Chrome has bugs in how it presents frames/iframes to extensions(Chrome用户的脚本是带有自动生成清单的扩展)。
因此,要解决这些错误,您必须注入注入的代码,该代码调用postMessage()
。
以下脚本显示了方法。它:
- 运行在iframe和包含页面中。
- 处理跨域iframes。
- 它表明具有下述逻辑脚本间控制:
- 容器页面设置以监听来自的IFRAME消息。
- iframe设置为侦听来自容器页面的消息。
- iframe将第一条消息发送到容器页面。
- 当容器页面收到该消息时,它会发送另一条消息回iframe。
安装此脚本:
// ==UserScript==
// @name _Cross iframe, cross-domain, interscript communication
// @include http://fiddle.jshell.net/9aQv5/*
// @include http://www.puppylinux.com/
// ==/UserScript==
console.log ("Script start...");
if (window.top === window.self) {
console.log ("Userscript is in the MAIN page.");
//--- Setup to process messages from the GM instance running on the iFrame:
window.addEventListener ("message", receiveMessageFromFrame, false);
console.log ("Waiting for Message 1, from iframe...");
}
else {
console.log ("Userscript is in the FRAMED page.");
//--- Double-check that this iframe is on the expected domain:
if (/puppylinux\.com/i.test (location.host)) {
window.addEventListener ("message", receiveMessageFromContainer, false);
//--- Send the first message to the containing page.
sendMessageFromAnIframe (
"***Message 1, from iframe***", "http://fiddle.jshell.net"
);
console.log ("Waiting for Message 2, from containing page...");
}
}
function receiveMessageFromFrame (event) {
if (event.origin != "http://www.puppylinux.com") return;
console.log ('The container page received the message, "' + event.data + '".');
//--- Send message 2, back to the iframe.
sendMessageToAnIframe (
"#testIframe",
"***Message 2, from the container page***",
"http://www.puppylinux.com"
);
}
function receiveMessageFromContainer (event) {
if (event.origin != "http://fiddle.jshell.net") return;
console.log ('The iframe received the message, "' + event.data + '".');
}
/*--- Because of bugs in how Chrome presents frames to extensions, we must inject
the messaging code. See bug 20773 and others.
frames, top, self.parent, contentWindow, etc. are all improperly undefined
when we need them. See Firefox and other browsers for the correct behavior.
*/
function sendMessageFromAnIframe (message, targetDomain) {
var scriptNode = document.createElement ('script');
scriptNode.textContent = 'top.postMessage ("' + message
+ '", "' + targetDomain + '");'
;
document.body.appendChild (scriptNode);
}
function sendMessageToAnIframe (cssSelector, message, targetDomain) {
function findIframeAndMessageIt (cssSelector, message, targetDomain) {
var targetIframe = document.querySelector (cssSelector)
if (targetIframe) {
targetIframe.contentWindow.postMessage (message, targetDomain);
}
}
var scriptNode = document.createElement ('script');
scriptNode.textContent = findIframeAndMessageIt.toString()
+ 'findIframeAndMessageIt ("' + cssSelector
+ '", "' + message
+ '", "' + targetDomain + '");'
;
document.body.appendChild (scriptNode);
}
console.log ("Script end");
然后参观this test page at jsFiddle。
你会在JavaScript控制台中看到这一点:
Script start...
Userscript is in the MAIN page.
Waiting for Message 1, from iframe...
Script end
Script start...
Userscript is in the FRAMED page.
Waiting for Message 2, from containing page...
Script end
The container page received the message, "***Message 1, from iframe***".
The iframe received the message, "***Message 2, from the container page***".
布洛克,我刚刚从假期回来,看到你的答案。非常感谢,我会详细研究并尝试将其应用于我的案例。 – Exilas 2012-08-20 23:31:15
@Exilas,好的。祝你好运。 – 2012-08-21 00:52:35
1)截至目前,postMessage可用于Chrome吗?你提到代码需要注入,因为chrome扩展有问题。这仍然是这样吗? 2)作为在postscript中使用postMessage的原始问题的扩展,是否有可能让网站本身拦截在postscript中使用postMessage? – Edge 2015-03-13 09:37:44