标签: postmessage

postMessage 或 addEventListener 不起作用

以下 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)

相应的小提琴:

http://jsfiddle.net/ZGvLg/3/

该消息从未收到。是什么原因?

html javascript postmessage

6
推荐指数
1
解决办法
8923
查看次数

如何检测子窗口何时关闭(而不是简单地刷新)?

我知道这些onbeforeunload事件onunload。除非我弄错了,否则这些都不是我需要的,因为每当当前页面卸载时它们都会触发\xe2\x80\x94,这意味着它们会在页面刷新时以及用户导航离开(到另一个 URL)时触发。

\n\n

我的场景是这样的。我创建了一个子窗口,用于window.open显示其他网站,用于审查目的(应用程序的用户根据各种标准审查网站)。子窗口需要频繁浏览,因此该onunload事件会频繁触发。

\n\n

我想知道浏览器窗口本身何时实际关闭,以便父窗口可以报告类似以下内容:

\n\n
\n

“您已关闭预览窗口;要重新打开它吗?”

\n
\n\n

这可能吗?

\n

javascript postmessage onbeforeunload dom-events

6
推荐指数
0
解决办法
3583
查看次数

双向 Javascript window.postMessage - 调度顺序问题

postMessage 可用于在窗口之间发送消息,通常是从 iframe 到父级或从父级到 iframe。

postMessage 仅在一个方向上发送数据并且是外联的 - 不像函数调用,函数调用从调用返回值并内联执行(后者是前者的条件)。

为了将信息发送回“调用者”,“被调用者”必须自己做postMessage

现在让我们假设我想测试一个合适的监听器是否存在:我会postMessage根据一些约定,如果监听器存在,它会postMessage回来。

在什么时候我可以确定没有听众?我如何实现等待?

我在 IE11、Chrome 和 Firefox 上尝试了以下实验:

  1. postMessage 收到消息后立即回发的 iframe 窗口
  2. 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)

javascript xss iframe postmessage

6
推荐指数
0
解决办法
1196
查看次数

无法在“窗口”上执行“postMessage”:目标来源无效

我有 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 的消息?

html iframe postmessage sandbox

6
推荐指数
1
解决办法
2万
查看次数

window.postMessage 在代码执行之前等待响应

我试图使示例更简单,实际上我的问题是在更复杂的上下文中。我有一个包含 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)

javascript asynchronous postmessage synchronous

6
推荐指数
0
解决办法
4842
查看次数

未收到使用 postMessage()

我确定这只是我的语法问题,但我正在尝试将变量发送到 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 的解释来尝试解决所有问题。

javascript postmessage

6
推荐指数
1
解决办法
8145
查看次数

如何在控制台应用程序中注册 WndProc

当我创建一个新的 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)

c++ windows postmessage console-application sendmessage

6
推荐指数
1
解决办法
4112
查看次数

如何在 Angular 6+ 中正确地将事件监听器附加到全局“窗口”?

背景

我们的Angular 6应用程序包含iframe一些第三方数据。为了实现安全的跨域通信,子 iframe 使用window.postMessage() API 将消息发布到父 Angular 应用程序。为了接收这些消息,父窗口必须附加一个事件监听器,例如window.addEventListener("message", callback)监听MessageEvents

问题

我需要监听 Angular 组件内的消息事件,但如何以windowAngular 方式正确访问全局对我来说并不明显。目前我想到的唯一解决方案是:

  1. MessageListenerService创建一个使用以下方法调用的 Angular 服务:

function listenForMessageEvent(callback) { this.renderer.listen('window', 'message', callback); }

注意: this.renderer这里是Angular 核心的Renderer2 。

  1. MessageListenerService.listenForMessageEvent()只需在我的自定义组件中使用即可。

我觉得这不是 Angular 世界的标准方法。有人可以在这里建议任何最佳实践吗?

多谢。

javascript iframe dom postmessage angular

6
推荐指数
1
解决办法
2万
查看次数

重定向弹出窗口并发布消息

我遇到了一个问题,我必须从弹出窗口重定向到不同的域并向其发布消息。这是场景:-

  1. 用户打开一个新的弹出窗口,该窗口保留在同一域中。(例如:http : //doamin_one.com
  2. 用户在弹出窗口中填写表单并单击提交。这应该将窗口重定向到http://doamin_two.com并且 domain_two.com 应该通过发布消息接收表单数据。

如果我打开新的弹出窗口并发布消息,我可以接收消息,但在重定向的情况下则无法接收消息。这是我的代码:

http://domain_one.com -

   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)

http://domain_two.com -

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)

javascript post postmessage window popup

6
推荐指数
1
解决办法
1340
查看次数

JavaScript:SharedArrayBuffer 上的 TextDecoder

我在 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

6
推荐指数
1
解决办法
1066
查看次数