JavaScript - Try & Catch - Устранение неполадок Window.postMessage() Ошибки

У меня возникают проблемы с поиском ошибок при использовании window.postMessage().

Я хочу уловить ошибку, которую я получаю -

"Не удалось отправить сообщение http://www.that-domain.com. Получатель имеет начало http://www.this-domain.com

Простой пример кода (если ошибка):

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

Более подробный поток процесса: Я добавляю перекрестный домен iframe в документ с помощью jQuery и затем отправляю на него. Это не должно быть ошибкой, потому что исходное происхождение цели должно совпадать - оба они задаются переменной 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');
}

Ответ 1

Похоже, в спецификации HTML5 указано, что если происхождение домена не совпадает, ошибка не возникает, и она должна прерываться молча.

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

10.4.3 Проводка сообщений - Часть № 9

"... если аргумент targetOrigin является абсолютным URL-адресом, а объект Document of Window, в котором был вызван метод, не имеет того же источника, что и targetOrigin, а затем отменяет эти шаги молча."

Ответ 2

Невозможно поймать ошибку, но обычно ошибка возникает, если исходное происхождение отличается от другого, это тестовый сценарий по сравнению с производственным сценарием.

Итак, вы можете проверить, что является родительским доменом, и соответственно изменить исходное происхождение:

function getTargetOrigin()
{
    try {
        var url = (window.location != window.parent.location) ? document.referrer : document.location.href;
        if (url.indexOf('www.myproduction-website.com')!=-1)
            return document.location.protocol + '//www.myproduction-website.com'
        else //set the alternative target
            return document.location.protocol + '//' + url.split('/')[2];
    }
    catch(e) //falback to production
    {
        return document.location.protocol + '//www.myproduction-website.com'
    }
}

и использовать его внутри функции postMessage:

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

С помощью этого решения вы можете использовать один и тот же код в конфигурации нескольких серверов без жесткого кодирования URL-адреса targetOrigin.

Это решение выходит из строя, если вы перемещаетесь внутри фрейма и проверяете документ .referrer, в этом случае он будет содержать не родительский URL-адрес, а предыдущий URL-адрес кадра. В этом случае рассмотрите использование '*' в качестве targetOrigin url, это единственное работающее решение для отправки сообщений в другие домены.

Надеюсь, что это поможет!

Ответ 3

Вы можете поймать ошибку на стороне приемника. В ванильном 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, если вы хотите обработать его там.