Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using postmessage to communicate with iframe - where is the error?

I have a Greasemonkey script that should send a postmessage to an embedded iframe where the same script starts a function. My attention is sending an easy message to trigger a function inside the iframe. The website and the iframe are not on the same domain. My js skills are quite bad and I can't find the issue.

Thx for reading

// ==UserScript==
// @name        Test
// @namespace   
// @include     domainA
// @include     domainB
// @version     1
// @grant       none
// ==/UserScript==

if ("domainA" === location.hostname)
{
  if (window === top) // prevents the script from running twice on domain A
  {
    window.setTimeout(delay, 15000);
    function delay()
    {
      console.log("Delay");
      document.getElementsByTagName("Iframe")[0].contentWindow.postMessage('message', 'domainB');  //The issue is probably here
    }
  }  
}
else // domain B 
{ 
 window.onmessage = function()  // or here
 {  
  console.log("Done"); // Didnt start
 }
}

edit: Iam using Firefox

like image 575
Winslow Fletcher Avatar asked Oct 17 '16 23:10

Winslow Fletcher


People also ask

Can you communicate with iframe?

All you have to do is first dispatch an event from the iframe to the parent that notifies the parent that the iframe is loaded (essentially a "ready message"). The parent will be listening for messages and if it receives the "ready message" event, it can then reply to the iframe with whatever message you want to send.

How do you communicate between two iframes?

Communicating directly between iframes is also possible by combining window. parent with target as defined above. In conclusion, the postMessage method is a more dynamic alternative to the single DOM, better suited if you load multiple pages in one iframe, but not always easier and it still requires the use of the DOM.


1 Answers

I don't believe you can do this within one script. If you create two scripts it will work. Make sure each script only includes the one domain.

First script that gets the iframe and posts the message to it:

// ==UserScript==
// @name        Test
// @namespace   
// @include     domainA
// @version     1
// @grant       none
// ==/UserScript==

if (window === top) // prevents the script from running twice on domain A
{
  window.setTimeout(delay, 15000);
  function delay()
  {
    console.log("Delay");
    document.getElementsByTagName("Iframe")[0].contentWindow.postMessage('message', 'domainB');  //The issue is probably here
  }
}

Second script that matches the domain of the iframe and attaches the event handler:

// ==UserScript==
// @name        Test IFrame
// @namespace   
// @include     domainB
// @version     1
// @grant       none
// ==/UserScript==

if (window.addEventListener) 
{
    window.addEventListener("message", function (event) 
    {  
        console.log("Done");
    }
}
else  // IE8 or earlier
{
    window.attachEvent("onmessage", function (event)
    {
        console.log("Done");
    }
}
like image 132
Steve Avatar answered Sep 28 '22 05:09

Steve