19

I'm trying to implement communication with postMessage. There is the main page which opens a popup with an iframe which comes from a different domain. This works fine so far but I want to catch the following error which occurs when I open the iFrame with a wrong origin.

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('myOriginURL') does not match the recipient window's origin ('myWindowsOrigin').

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

the problem is that the code never runs into the catch block. Interesting part is that chrome shows an error in the console while all other major browser just don't do anything (no alert, no error)

How can I handle the error in the postMessage?

Cœur
  • 32,421
  • 21
  • 173
  • 232
Arikael
  • 1,759
  • 1
  • 15
  • 45
  • Did you find a solution to this? I suspect it is happening because the error is technically in the domain that is receiving the message. – SystemicPlural Jul 01 '14 at 07:16
  • I think the problem was elsewhere, because the script now works in our environment. here's what's currently in the receiving site, maybe someone can benefit from it if (window.addEventListener) { window.addEventListener("message", function (e) { if (e.origin !== 'POSTING_URL') { return; } //do stuff }` – Arikael Sep 16 '14 at 13:40
  • I'm struggling with the formatting of the code... But I hope you get the idea. The script is added in document.ready or window.load – Arikael Sep 16 '14 at 13:46
  • The browser is printing an error, but `postMessage` isn't actually throwing an exception -- so there's nothing to catch. – starwed Oct 16 '18 at 20:47

3 Answers3

1

I think this is made on purpose. Your context should not know if the message was sent successfully, or not (for security purposes)

licancabur
  • 615
  • 4
  • 11
0

I've just run into a similar issue, and tried this solution:

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');
  }
}

Short answer: this forces the try block to end before the postMessage, if you do not have access to the top window. (thus you catch the error)

Long answer:

My context: I have a parent page with n iframes. Some iframes are from mydomain.com other are from otherdomains.com

Problem: How can an iframe from mydomain.com communicate with all other iframes (mydomain.com) by postMessage, without generating the error Failed to execute 'postMessage'....

Possible solution:

/** 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);
    }
}

Tested it in Chrome, it works in my case.

Dharman
  • 21,838
  • 18
  • 57
  • 107
verjas
  • 1,638
  • 1
  • 10
  • 17
-4

This is because the error is occuring in the domain that you are loading into the iFrame. Surround the code that posts the message with the try{}catch(e){} block and send an appropriate error message to the listener to handle it there.

try{
parent.postMessage({"success":true,"usertoken":localStorage.token},"*");
}
catch(e){
parent.postMessage({"success":false},"*");

}
Mad Scientist
  • 320
  • 4
  • 13