Search code examples
javascriptgoogle-chrome-extension

Chrome Extension: IFrame and listening to clicks within it


I would like to insert an iframe (frame.html which is part of my extension) into the body of a website and then be able to receive click events for two buttons inside it.

Running into problems with same origin policy, etc.

I'm sure there is a relatively graceful workaround for this, but I'm not having much luck finding it.


Solution

  • You can use message events to let the injected iframe window communicate with the content script (take care about security).

    Here is a simple example. The extension injects an IFRAME element into all viewed pages via a content script. The frame contains a page with a button. The button has a click handler which sends a message to the top window. The content script has a listener to messages coming from the iframe which opens an alert displaying the message data.

    manifest.json:

    {
      "name": "Test",
      "version": "0.0.1",
      "content_scripts": [ {
        "matches": [ "http://*/*", "https://*/*" ],
        "js": [ "content.js" ],
        "run_at" : "document_end"
      } ]
    }
    

    content.js:

    var iframe = document.createElement("iframe");    
    iframe.src = chrome.runtime.getURL("iframe.html");
    document.body.appendChild(iframe);
    
    addEventListener("message", function(event) {
      if (event.origin + "/" == chrome.runtime.getURL(""))
        alert(event.data);
    }, false);
    

    iframe.html:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Test</title>
    </head>
    <body>
      <button id="button">Click me!</button>
      <script>
        document.getElementById("button").addEventListener("click", function() {
          top.postMessage("clicked!", "*");
        }, false);
      </script>
    </body>
    </html>