无法使用 Chrome 扩展中的 postMessage 从父 window 向 iframe 发送数据
Unable to send data to iframe from parent window using postMessage in Chrome Extension
我正在开发一个 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
只是为了确保当我 post 消息时 iframe 是 available/loaded。
现在,我在 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
函数无法工作。这可能是什么原因?
P.S。我能够从 iframe 向父级发送消息,但反之则不行。
在我看来,使用 postMessage()
方法仍然是跨域传递消息的更安全的方式。
要使用此方法,请注意它接受两个参数:
message
– 将发送给接收方的字符串或对象
window.
targetOrigin
– 正在发送消息的 window 的 URL
到。目标 window 的协议、端口和主机名必须匹配
要发送的消息的此参数。指定“*”将匹配
任何 URL 但是出于安全原因,强烈建议不要这样做。
并且,应该在消息设置到的 window 上调用此方法。可以通过多种不同的方式获得对目标 window 的引用:
- 当使用
window.open()
时,将引用新的 window
由 open()
方法返回。
- 对于 iframe,您可以访问
contentWindow
属性
框架。
targetWindow.postMessage('Hello World!', 'http://example.com');
此博客中提供了使用技巧、有关实施的更多信息和完整指南 - Cross-Domain Messaging With postMessage and I think this SO post - Invoking JavaScript code in an iframe from the parent page 也会有所帮助。
尝试不使用 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>
我正在开发一个 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
只是为了确保当我 post 消息时 iframe 是 available/loaded。
现在,我在 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
函数无法工作。这可能是什么原因?
P.S。我能够从 iframe 向父级发送消息,但反之则不行。
在我看来,使用 postMessage()
方法仍然是跨域传递消息的更安全的方式。
要使用此方法,请注意它接受两个参数:
message
– 将发送给接收方的字符串或对象 window.targetOrigin
– 正在发送消息的 window 的 URL 到。目标 window 的协议、端口和主机名必须匹配 要发送的消息的此参数。指定“*”将匹配 任何 URL 但是出于安全原因,强烈建议不要这样做。
并且,应该在消息设置到的 window 上调用此方法。可以通过多种不同的方式获得对目标 window 的引用:
- 当使用
window.open()
时,将引用新的 window 由open()
方法返回。 - 对于 iframe,您可以访问
contentWindow
属性 框架。targetWindow.postMessage('Hello World!', 'http://example.com');
此博客中提供了使用技巧、有关实施的更多信息和完整指南 - Cross-Domain Messaging With postMessage and I think this SO post - Invoking JavaScript code in an iframe from the parent page 也会有所帮助。
尝试不使用 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>