1

I'm developing a Google Chrome Extension that injects a script on a webpage, gather some data from the web page, call an iframe and send that data to the iframe. Since this process needs to be cross-domain, postMessage was the only thing i could think of for implementing this however i'm not able to receive this data in iframe.
(Btw, is there any other method by which i can achieve same functionality?)

Below is my script that i inject on a webpage when a user clicks on the extension.

jQuery('body').append('<div style="height: 100% !important; width: 100% !important; position: fixed !important; margin: 0% auto !important; background: rgba(17, 17, 17, 0.9) !important; left: 0 !important; right: 0 !important; z-index: 99999999 !important; top: 0% !important;" id="image-grabber-container"><iframe id="vwframe" src="https://example.com/abcd.php"  frameborder="0" style="display: block !important; position: fixed !important; height: 100% !important; width: 100% !important; top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px !important; margin: 0px !important; clip: auto !important; z-index: 7147483657 !important;"></iframe></div>');

setTimeout(function(){
    var dTitle = document.title;
    var receiver = document.getElementById('vwframe').contentWindow;
    receiver.postMessage(dTitle, '*');
},1000);


I've used setTimeout here just to make sure that iframe is available/loaded when i post message.

Now, i call a script in the iframe to receive the message:

window.onload = function() {
        function receiveMessage1(e) {
            console.log('mSG');
            if (e.origin !== currentUrl)
                return;

            parentTitle = e.data;
            console.log(parentTitle);
        }
        if (window.addEventListener){
            console.log('if');
          window.addEventListener("message", receiveMessage1, false);
          console.log('if end');
        } else {
            console.log('else');
          attachEvent("onmessage", receiveMessage1);
          console.log('else end');
        }
}


I see no error in console however receiveMessage1 function fails to work. What could be the possible reason for this?

P.S. I was able to send message from iframe to parent but not vice versa.

Tushar Shukla
  • 5,666
  • 2
  • 27
  • 41

2 Answers2

1

Try not using setTimeout and window.onload, just this instead:

<script>

    function receiveMessage1(e) {
        console.log('mSG');
        if (e.origin !== currentUrl)
            return;

        parentTitle = e.data;
        console.log(parentTitle);
    }
    if (window.addEventListener){
        console.log('if');
      window.addEventListener("message", receiveMessage1, false);
      console.log('if end');
    } else {
        console.log('else');
      attachEvent("onmessage", receiveMessage1);
      console.log('else end');
    }
</script>
jcubic
  • 61,973
  • 54
  • 229
  • 402
  • Thanks for the answer but it still is not showing me `console.log('mSG')`. Any possible error that i might be doing in this? – Tushar Shukla May 31 '16 at 09:12
  • Finally i got a glimpse of this working but, it is not working always. Sounds quite stupid to me but what exactly is happening that it works barely 2 out of 10 times. And what i mean from 'WORKING' is it shows 'mSG' in console. – Tushar Shukla May 31 '16 at 10:03
  • @TusharShukla Maybe use `$('iframe').load(function() {` instead of `setTimeout`. – jcubic May 31 '16 at 12:49
  • A 1000 upvotes for you (only if i could :p).. Thanks a lot – Tushar Shukla May 31 '16 at 13:44
0

In my opinion, using postMessage() method is still the more secure way of passing messages across domains.

To use this method, please note that it accepts two parameters:

  • message – A string or object that will be sent to the receiving window.
  • targetOrigin – The URL of the window that the message is being sent to. The protocol, port and hostname of the target window must match this parameter for the message to be sent. Specifying "*" will match any URL however this is strongly discouraged for security reasons.

And, this method should be called on the window that the message is being set to. A reference to the target window can be obtained in a number of different ways:

  • When using window.open() a reference to the new window will be returned by the open() method.
  • For iframes you can access the contentWindow property on the desired iframe.

    targetWindow.postMessage('Hello World!', 'http://example.com');

Usage tips, more information regarding the implementation and complete guide are given in this blog - Cross-Domain Messaging With postMessage and I think this SO post - Invoking JavaScript code in an iframe from the parent page will be helpful too.

Community
  • 1
  • 1
Teyam
  • 7,686
  • 3
  • 15
  • 22