以下 JavaScript 代码使用 HTML5 postMessage / addEventListener 函数向自身发送消息:
window.addEventListener('testMsg', function(event) {
alert('got a message'); /* Never happens. Why? */
}, false );
window.addEventListener('load', function(event) {
alert('sending message');
window.postMessage('testMsg', '*');
}, false);
Run Code Online (Sandbox Code Playgroud)
相应的小提琴:
该消息从未收到。是什么原因?
我知道这些onbeforeunload事件onunload。除非我弄错了,否则这些都不是我需要的,因为每当当前页面卸载时它们都会触发\xe2\x80\x94,这意味着它们会在页面刷新时以及用户导航离开(到另一个 URL)时触发。
我的场景是这样的。我创建了一个子窗口,用于window.open显示其他网站,用于审查目的(应用程序的用户根据各种标准审查网站)。子窗口需要频繁浏览,因此该onunload事件会频繁触发。
我想知道浏览器窗口本身何时实际关闭,以便父窗口可以报告类似以下内容:
\n\n\n\n\n“您已关闭预览窗口;要重新打开它吗?”
\n
这可能吗?
\npostMessage 可用于在窗口之间发送消息,通常是从 iframe 到父级或从父级到 iframe。
postMessage 仅在一个方向上发送数据并且是外联的 - 不像函数调用,函数调用从调用返回值并内联执行(后者是前者的条件)。
为了将信息发送回“调用者”,“被调用者”必须自己做postMessage。
现在让我们假设我想测试一个合适的监听器是否存在:我会postMessage根据一些约定,如果监听器存在,它会postMessage回来。
在什么时候我可以确定没有听众?我如何实现等待?
我在 IE11、Chrome 和 Firefox 上尝试了以下实验:
postMessage 收到消息后立即回发的 iframe 窗口postMessage 自己的窗口作为在事件处理中调度未来点的一种手段以下是这些步骤的代码:
var iframe = document.getElementById('iframe');
iframe.contentWindow.postMessage('hello', '*');
window.postMessage('schedule', '*')
Run Code Online (Sandbox Code Playgroud)
iframe 的响应代码是这样的:
window.addEventListener('message', function (event) {
window.top.postMessage('echo ' + event.data, '*');
}, false);
Run Code Online (Sandbox Code Playgroud)
父窗口的侦听器本身是这样的:
var n = 0;
window.addEventListener("message", function (event) {
if (n > 4) return;
console.info(event.data);
window.postMessage('(repeat of ' + event.data + ' #' + n + ')', …Run Code Online (Sandbox Code Playgroud) 我有 iframe:
<iframe id="GameFrame"
sandbox="allow-scripts allow-pointer-lock"
src="https://127.0.0.1:112/games/1047/play">
</iframe>
Run Code Online (Sandbox Code Playgroud)
我的父页面位于:
https://127.0.0.1/arcade/not-hidden/space-blaster-1047
Run Code Online (Sandbox Code Playgroud)
我正在尝试向 iFrame 发布消息:
var gameIframe = $("#GameFrame");
gameIframe.get(0).contentWindow.postMessage("screenshot", "");
Run Code Online (Sandbox Code Playgroud)
但这会引发错误:
未捕获的语法错误:无法在“窗口”上执行“postMessage”:在调用“postMessage”时目标源“无效”。
其他尝试:
postMessage("screenshot", "https://127.0.0.1");
Run Code Online (Sandbox Code Playgroud)
无法在“DOMWindow”上执行“postMessage”:提供的目标源(“ https://127.0.0.1 ”)与收件人窗口的源(“null”)不匹配。
我怎样才能得到这个发布到 iFrame 的消息?
我试图使示例更简单,实际上我的问题是在更复杂的上下文中。我有一个包含 iframe (child.htm) 的 html 页面 (parent.htm)。html 页面和 iframe 位于不同的域中,因此我使用 window.postMessage 进行相互通信。
这是parent.htm的代码:
<html>
<head>
<script>
if (window.addEventListener){
window.addEventListener("message",getMessage,false);
} else if (window.XMLHttpRequest){
window.attachEvent("onmessage",getMessage);
}
function getMessage(event){
if(event.data=="getCity"){
window.myIframe.postMessage("London","*");
}
}
</script>
</head>
<body>
<div style="height:100%;width:100%">
<iframe name="myIframe" src="child.htm"></iframe>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
以及child.htm的代码
<html>
<head>
<script>
if (window.addEventListener){
window.addEventListener("message",getValue,false);
} else if (window.XMLHttpRequest){
window.attachEvent("onmessage",getValue);
}
var returnValue="";
function getValue(event){
returnValue=event.data;
}
function getCityFromTop(){
top.postMessage("getCity","*");
return returnValue;
}
</script>
</head>
<body>
<a href="javascript:alert(getCityFromTop())">Get city from top</a>
<br/>
<a href="javascript:alert(returnValue)">Show city after …Run Code Online (Sandbox Code Playgroud) 我确定这只是我的语法问题,但我正在尝试将变量发送到 iframe(供 colorbox 使用)。目前我接受两端的任何域(只是为了让它工作)。这是发送页面的js:
$(document).ready(function() {
if(window.location.hash) {
var urlimage = window.location.hash.substring(1);
targetiframe = document.getElementById('wbgallery').contentWindow;
targetiframe.postMessage(urlimage, "*");
console.log(urlimage);
}
});
Run Code Online (Sandbox Code Playgroud)
这是接收页面:
$(document).ready(function() {
window.addEventListener('message',receiveMessage);
console.log(event);
function receiveMessage(event) {
if (origin !== "*")
return;
inbound = event.data;
console.log(inbound);
}
});
Run Code Online (Sandbox Code Playgroud)
我看到了 urlimage 的控制台日志,可以看到一个事件,但没有任何入站事件。我正在使用Mozilla 的解释来尝试解决所有问题。
当我创建一个新的 Win32 应用程序时,我注意到了这个函数:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Run Code Online (Sandbox Code Playgroud)
当某处调用函数PostMessage或 SendMessage时会收到消息,我注意到函数 WndProc 可以接收消息,因为有一个函数注册它:
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SCREENCAPTURE));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SCREENCAPTURE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
Run Code Online (Sandbox Code Playgroud)
注意: wcex.lpfnWndProc = WndProc;
我想了解 PostMessage() 的机制以及如何接收它,所以我创建了一个 C++ 控制台应用程序,看看我是否可以注册函数 WndProc,这是我的尝试代码:
LRESULT …Run Code Online (Sandbox Code Playgroud) 背景
我们的Angular 6应用程序包含iframe一些第三方数据。为了实现安全的跨域通信,子 iframe 使用window.postMessage() API 将消息发布到父 Angular 应用程序。为了接收这些消息,父窗口必须附加一个事件监听器,例如window.addEventListener("message", callback)监听MessageEvents
问题
我需要监听 Angular 组件内的消息事件,但如何以windowAngular 方式正确访问全局对我来说并不明显。目前我想到的唯一解决方案是:
MessageListenerService创建一个使用以下方法调用的 Angular 服务:function listenForMessageEvent(callback) {
this.renderer.listen('window', 'message', callback);
}
注意: this.renderer这里是Angular 核心的Renderer2 。
MessageListenerService.listenForMessageEvent()只需在我的自定义组件中使用即可。我觉得这不是 Angular 世界的标准方法。有人可以在这里建议任何最佳实践吗?
多谢。
我遇到了一个问题,我必须从弹出窗口重定向到不同的域并向其发布消息。这是场景:-
如果我打开新的弹出窗口并发布消息,我可以接收消息,但在重定向的情况下则无法接收消息。这是我的代码:
function redirect(formData,popup) {
//popup=window ref object
popup.location.href="http://domain_two.com"
popup.postMessage(JSON.stringify(formData),
"http://domain_two.com");
}
Run Code Online (Sandbox Code Playgroud)
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if (event.origin !== "http://domain_one.com")
return;
let data=event.data;
//....
}
Run Code Online (Sandbox Code Playgroud) 我在 SharedArrayBuffer 上遇到解码()问题。
代码:
var sharedArrayBuffer = new SharedArrayBuffer(2);
var uint8Array = new Uint8Array(sharedArrayBuffer);
uint8Array[0] = 20;
var decoder = new TextDecoder();
decoder.decode(uint8Array);
Run Code Online (Sandbox Code Playgroud)
错误:
Failed to execute 'decode' on 'TextDecoder': The provided ArrayBufferView value must not be shared.
Run Code Online (Sandbox Code Playgroud)
这里有一个规范警告开发人员有关此类内存的竞争条件。我可以以某种方式强制解码吗?我确信解码期间数据不会改变。或者有解决方法吗?
原因: 我想创建 Uint8Array 的单个副本并将其传递,而不通过 postmessage 复制(如果未指定可传输,则默认复制)到多个(> 3)IFrame(带有沙箱标记)。也许还有其他可能的解决方案?
javascript postmessage uint8array sharedarraybuffer textdecoder
postmessage ×10
javascript ×8
iframe ×3
html ×2
angular ×1
asynchronous ×1
c++ ×1
dom ×1
dom-events ×1
popup ×1
post ×1
sandbox ×1
sendmessage ×1
synchronous ×1
textdecoder ×1
uint8array ×1
window ×1
windows ×1
xss ×1