top.postMessage原始错误没有被捕获

时间:2014-05-27 07:27:05

标签: javascript try-catch postmessage

我试图与postMessage实现通信。有一个主页面打开一个带有iframe的弹出窗口,它来自不同的域。 到目前为止这工作正常,但我想捕获以下错误,当我打开具有错误原点的iFrame时会发生此错误。

  

无法执行' postMessage'在' DOMWindow':提供的目标来源(' myOriginURL')与收件人窗口的来源(' myWindowsOrigin')不匹配。

origin = 'http://www.myorigin.ch';
if (window.postMessage) {
  try {
     top.postMessage('hello', origin);
  } 
  catch(ex) {
     alert('an error occured');
  }
}

问题是代码永远不会进入catch块。有趣的是,Chrome在控制台中显示错误,而所有其他主要浏览器都没有做任何事情(没有警报,没有错误)

如何处理postMessage中的错误?

2 个答案:

答案 0 :(得分:1)

我认为这是故意的。您的上下文不应该知道消息是否已成功发送(出于安全目的)

答案 1 :(得分:0)

我刚刚遇到了类似的问题,并尝试了这个解决方案:

origin = 'http://www.myorigin.ch';
if (window.postMessage) {
  try {
    // ---> add this IF condition:
    if (top.origin)
      top.postMessage('hello', origin);
  } 
  catch(ex) {
    alert('an error occured');
  }
}

简短回答:如果您无权访问顶部窗口,这将强制 try 块在 postMessage 之前结束。 (因此您会发现错误)

长答案:

我的上下文:我有一个带有 n 个 iframe 的父页面。一些 iframe 来自 mydomain.com 其他来自 otherdomains.com

问题:来自 mydomain.com 的 iframe 如何通过 postMessage< 与所有其他 iframe (mydomain.com) 通信/em>,没有产生错误 Failed to execute 'postMessage'....

可能的解决方案

/** Note: this runs from inside an iFrame (mydomain.com) **/
/** Objective: communicate with all other iFrames that have the desired origin **/
/** Desired origin = window.origin (meaning the origin of this frame) **/

// get all iFrames in Parent page
for (let i = 0; i < window.parent.frames.length; i++) {
    // skip the iframe that equals self
    if (window.parent.frames[i] == window)
        continue;
    
    // check if you are allowed to access the target iframe
    // meaning that it is from the desired origin
    try {
        // if this is allowed...
        if (window.parent.frames[i].origin) {
            // ... then I can send a postMessage
            window.parent.frames[i].postMessage("Hello World!", window.origin);
        }
        // (if it was't allowed, then postMessage was not executed)

    } catch (err) {
        // if it was not allowed, then the error is caught
        // and no further 'Failed to execute...' is shown..
        
        console.log("Caught it!", err);
    }
}

在 Chrome 中测试过,它适用于我的情况。