JavaScript - 尝试&捕获 - 捕获Window.postMessage()错误

时间:2013-06-13 06:19:58

标签: javascript jquery html5 iframe cross-domain

使用window.postMessage()时遇到错误。

我希望能够捕获我得到的错误 -

“无法向http://www.that-domain.com发帖。收件人来源http://www.this-domain.com

简单示例代码(应该是错误):

 try {
    window.postMessage('1','http://www.differentDomain.com');
 } 
 catch (e) {       
     alert('error');
 }

更详细的流程: 我正在使用jQuery向文档添加跨域iframe,然后发布到它。这不应该是错误,因为目标来源应该匹配 - 它们都由proxyDomain变量设置。

var $iframeProxy = $('<iframe id="myIFrame" src="' + proxyDomain + '"></iframe>').appendTo('body');

window.storageProxy = $iframeProxy[0].contentWindow;

try {
    window.storageProxy.postMessage(message, proxyDomain);
}
catch (e) {       
    alert('error');
}

4 个答案:

答案 0 :(得分:3)

无法捕获错误,但通常如果目标来源不同则会发生错误,案例是测试与生产方案。

因此,您可以检查什么是父域并相应地更改目标源:

function postMessage(message){
    window.top.postMessage( message,getTargetOrigin());
}

并在postMessage函数中使用它:

percent_difference(1.0, 2.0)

使用此解决方案,您可以在多服务器配置中使用相同的代码,而无需对targetOrigin网址进行硬编码。

如果您在框架内导航并重新检查document.referrer,则此解决方案将失败,在这种情况下,它将不包含父网址,而是包含前一帧网址。 在这种情况下,考虑使用'*'作为targetOrigin url,它是向其他域发送消息的唯一可行解决方案。

希望它有所帮助!

答案 1 :(得分:2)

看起来在HTML5规范中概述了如果域起源不匹配,则不会抛出任何错误,它应该以静默方式中止。

http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#web-messaging

10.4.3发布消息 - 第9部分

“...如果targetOrigin参数是绝对URL,并且调用该方法的Window对象的Document与targetOrigin的原点不同,则以静默方式中止这些步骤。”

答案 2 :(得分:0)

我将在matteo-conta的解决方案中添加更高的安全性,以防止像www.myproduction-website.com.fakedomain.com这样的虚假域接收消息:

function getTargetOrigin() {
    const domainDev = 'mydev-website.com';
    const domainProd = 'myproduction-website.com';
    try {
        var url = (window.location !== window.parent.location) ? document.referrer : document.location.href;
        const domain = url.split('/')[2];
        if (domain.endsWith(domainDev) || domain.endsWith(domainProd))
            return document.location.protocol + domain;
        else return '';
    } catch(e) {
        return ''
    }
}
const targetOrigin = getTargetOrigin();
try{
    if (targetOrigin) window.parent.postMessage(${msg}, targetOrigin);
} catch(e) {
    window.parent.postMessage(e, '*')
}

我还添加了将错误消息发布到任何targetOrigin的功能,以便您可以使用以下方法在网站的末尾捕获该消息:

window.addEventListener("message", onResponse, false);
onResponse(res) {
    const data = _.get(res, 'data');
    if (res.origin === 'iframe-url-goes-here') {
        console.log('message from iframe', data)
    }
}

答案 3 :(得分:-1)

您可以在接收器端捕获错误。在vanilla javascript中你可以做到:

window.addEventListener('message', function() {
    try {
        not.existing.objects = 'Something dangerous!';
    } catch(e) {
        console.log('error at message receive: ' + e + ' stack trace: ' + e.stack);
    }
}, false);

如果你想在那里处理它,你可以将它发送回catch块中的主页。