这两个脚本实例可以使用postMessage()
. 关于:
这将需要同步实例,例如让 iframe 仅在网页完成后执行其任务,反之亦然。
这就是其他答案中显示的内容。
但是 Chrome 在如何向扩展提供帧/iframe
方面存在错误,因此,要解决这些错误,您必须注入调用postMessage()
.
以下脚本显示了如何。它:
- 在 iframe 和包含页面中运行。
- 处理跨域 iframe。
- 它演示了具有以下逻辑的脚本间控制:
- 容器页面设置为侦听来自 iframe 的消息。
- iframe 设置为侦听来自容器页面的消息。
- iframe 将第一条消息发送到容器页面。
- 当容器页面收到该消息时,它会将另一条消息发送回 iframe。
安装这个脚本(感谢CertainPerformance,多年来目标站点的变化):
// ==UserScript==
// @name _Cross iframe, cross-domain, interscript communication
// @include http://fiddle.jshell.net/2nmfk5qs/*
// @include http://puppylinux.com/
// @grant none
// ==/UserScript==
/* eslint-disable no-multi-spaces */
if (window.top === window.self) return;
console.log ("Script start...");
if (window.location.href.includes('fiddle')) {
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://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://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 = 'parent.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");
然后在 jsFiddle访问这个测试页面。
您将在 javascript 控制台中看到:
脚本开始...
用户脚本位于 MAIN 页面中。
等待消息 1,来自 iframe...
脚本结束
脚本开始...
用户脚本位于 FRAMED 页面中。
等待消息 2,来自包含页面...
脚本结束
容器页面收到消息“***Message 1, from iframe***”。
iframe 收到消息“***Message 2, from the container page***”。