我正在开发一个Google Chrome扩展程序,它可以在网页上注入脚本,从网页中收集一些数据,调用iframe并将该数据发送到iframe。由于此过程需要跨域,因此postMessage是我唯一能想到的实现此过程的方法,但是我无法在iframe中接收此数据。
(顺便说一句,还有其他方法可以实现相同的功能吗?
下面是当用户单击扩展程序时我在网页上注入的脚本。
jQuery('body').append('<div style="height: 100% !important; width: 100% !important; position: fixed !important; margin: 0% auto !important; background: rgba(17, 17, 17, 0.9) !important; left: 0 !important; right: 0 !important; z-index: 99999999 !important; top: 0% !important;" id="image-grabber-container"><iframe id="vwframe" src="https://example.com/abcd.php" frameborder="0" style="display: block !important; position: fixed !important; height: 100% !important; width: 100% !important; top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px !important; margin: 0px !important; clip: auto !important; z-index: 7147483657 !important;"></iframe></div>');
setTimeout(function(){
var dTitle = document.title;
var receiver = document.getElementById('vwframe').contentWindow;
receiver.postMessage(dTitle, '*');
},1000);
我在这里使用setTimeout
只是为了确保在我发布消息时 iframe 可用/加载。
现在,我在 iframe 中调用一个脚本来接收消息:
window.onload = function() {
function receiveMessage1(e) {
console.log('mSG');
if (e.origin !== currentUrl)
return;
parentTitle = e.data;
console.log(parentTitle);
}
if (window.addEventListener){
console.log('if');
window.addEventListener("message", receiveMessage1, false);
console.log('if end');
} else {
console.log('else');
attachEvent("onmessage", receiveMessage1);
console.log('else end');
}
}
我在控制台中没有看到任何错误receiveMessage1
但是该功能无法正常工作。可能是什么原因?
附言我能够将消息从 iframe 发送到父级,但反之亦然。
尽量不要使用 setTimeout 和 window.onload,只是这个:
<script>
function receiveMessage1(e) {
console.log('mSG');
if (e.origin !== currentUrl)
return;
parentTitle = e.data;
console.log(parentTitle);
}
if (window.addEventListener){
console.log('if');
window.addEventListener("message", receiveMessage1, false);
console.log('if end');
} else {
console.log('else');
attachEvent("onmessage", receiveMessage1);
console.log('else end');
}
</script>
在我看来,使用postMessage()
方法仍然是跨域传递消息的更安全方式。
要使用此方法,请注意它接受两个参数:
message
– 将发送给接收方的字符串或对象 窗。targetOrigin
– 发送消息的窗口的 URL 自。目标窗口的协议、端口和主机名必须匹配 要发送的消息的此参数。指定"*"将匹配 任何 URL,但出于安全原因,强烈建议不要这样做。
并且,应在设置消息的窗口上调用此方法。可以通过多种不同的方式获取对目标窗口的引用:
- 使用
window.open()
时,对新窗口的引用将是 由open()
方法返回。 - 对于 iframe,您可以访问所需
contentWindow
属性 iframe。targetWindow.postMessage('Hello World!', 'http://example.com');
使用技巧,有关实现的更多信息和完整指南在此博客中给出 - 使用postMessage进行跨域消息传递,我认为这篇SO帖子 - 从父页面在iframe中调用JavaScript代码也会有所帮助。