Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 用户脚本的两个实例如何在帧之间通信?_Javascript_Iframe_Synchronization_Cross Domain_Userscripts - Fatal编程技术网

Javascript 用户脚本的两个实例如何在帧之间通信?

Javascript 用户脚本的两个实例如何在帧之间通信?,javascript,iframe,synchronization,cross-domain,userscripts,Javascript,Iframe,Synchronization,Cross Domain,Userscripts,请参阅在网页和iframe中运行相同JavaScript的技术,如下所示: 例如,假设您在domain_A.com上有此页面: 然后脚本将运行两次——一次在主页上,一次在iframe上,就像它是一个独立的页面一样 让脚本的两个实例彼此通信的选项是什么 这是同步实例所必需的。例如,让iframe脚本实例仅在网页脚本实例完成后执行其任务,反之亦然。这两个脚本实例可以使用。关于: 这是同步实例所必需的,例如,让iframe仅在webpage one完成后执行其任务,反之亦然 如图所示。 但是 因此,

请参阅在网页和iframe中运行相同JavaScript的技术,如下所示:

例如,假设您在domain_A.com上有此页面:

然后脚本将运行两次——一次在主页上,一次在iframe上,就像它是一个独立的页面一样


让脚本的两个实例彼此通信的选项是什么


这是同步实例所必需的。例如,让iframe脚本实例仅在网页脚本实例完成后执行其任务,反之亦然。

这两个脚本实例可以使用。关于:

这是同步实例所必需的,例如,让iframe仅在webpage one完成后执行其任务,反之亦然

如图所示。
但是 因此,要解决这些bug,必须插入调用
postMessage()
的代码

下面的脚本演示了如何使用。它:

  • 在iframe和包含页面中运行
  • 处理跨域iframe
  • 它演示了具有以下逻辑的脚本间控制:
  • 容器页面设置为侦听来自iframe的消息
  • iframe设置为侦听来自容器页面的消息
  • iframe将第一条消息发送到容器页面
  • 当容器页面收到该消息时,它将另一条消息发送回iframe
安装此脚本(由于目标站点多年来的更改,由于CertainPerformance而更新):

/==UserScript==
//@name\u跨iframe、跨域、脚本间通信
//@包括http://fiddle.jshell.net/2nmfk5qs/*
//@包括http://puppylinux.com/
//@grant none
//==/UserScript==
/*eslint不禁用多个空格*/
如果(window.top==window.self)返回;
console.log(“脚本启动…”);
if(window.location.href.includes('fiddle')){
console.log(“用户脚本位于主页面中”);
//---用于处理来自iFrame上运行的GM实例的消息的设置:
window.addEventListener(“消息”,receiveMessageFromFrame,false);
console.log(“正在等待来自iframe的消息1…”);
}
否则{
console.log(“Userscript在框架页面中”);
//---仔细检查此iframe是否位于预期域上:
if(/puppylinux\.com/i.test(location.host)){
window.addEventListener(“消息”,receiveMessageFromContainer,false);
//---将第一条消息发送到包含该消息的页面。
sendMessageFromAnIframe(
***来自iframe***的消息1http://fiddle.jshell.net"
);
console.log(“正在等待消息2,来自包含页面…”);
}
}
函数receiveMessageFromFrame(事件){
如果(event.origin!“http://puppylinux.com)返回;
console.log('容器页面收到消息“'+event.data+'”);
//---将消息2发送回iframe。
sendMessageToAnIframe(
“#测试框架”,
“***消息2,来自容器页面***”,
"http://puppylinux.com"
);
}
函数receiveMessageFromContainer(事件){
如果(event.origin!“http://fiddle.jshell.net)返回;
console.log('iframe接收到消息“'+event.data+'”);
}
/*---由于Chrome向扩展提供框架的方式存在缺陷,我们必须注入
消息传递代码。请参阅bug 20773和其他。
框架、顶部、self.parent、contentWindow等都未正确定义
当我们需要的时候。有关正确的行为,请参阅Firefox和其他浏览器。
*/
函数sendMessageFromAnIframe(消息,targetDomain){
var scriptNode=document.createElement('script');
scriptNode.textContent='parent.postMessage(“')+消息
+“,“'+targetDomain+”);'
;
document.body.appendChild(脚本节点);
}
函数sendMessageToAnIframe(CSS选择器、消息、目标域){
函数FindFrameAndMessageIt(cssSelector、message、targetDomain){
var targetFrame=document.querySelector(cssSelector)
if(目标帧){
targetFrame.contentWindow.postMessage(消息,targetDomain);
}
}
var scriptNode=document.createElement('script');
scriptNode.textContent=FindFrameAndMessageIt.toString()
+'FindFrameAndMessageIt(“+CSS选择器
+“,”+消息
+“,“'+targetDomain+”);'
;
document.body.appendChild(脚本节点);
}
console.log(“脚本结束”);

然后访问。

您将在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***". 脚本开始。。。 用户脚本位于主页面中。 正在等待来自iframe的消息1。。。 脚本结束 脚本开始。。。 Userscript位于框架页面中。 正在等待来自包含页面的消息2。。。 脚本结束 容器页面收到消息“***消息1,来自iframe***”。 iframe从容器页面***接收到消息“***消息2”。
布罗克,我刚度假回来,看到了你的答案。非常感谢,我将详细研究它,并尝试将其应用到我的案例中。1)到目前为止,postMessage在chrome中可用吗?您提到需要注入代码,因为chrome扩展有问题。还是这样吗?2) 作为对关于用户脚本中使用postMessage的原始问题的扩展,网站本身是否可以拦截用户脚本中的postMessage使用?@Edge:是和是(但如果您在Tampermonkey中使用脚本并设置
@grant none
,则可能不需要注入)。是的,在很多情况下,网页可以截获postmessage。我还没有看到一个真正的网站,但肛门/偏执
// @match http://domain_A.com/*
// @match http://domain_B.com/*
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***".