ruda
ruda

Reputation: 181

Accessing an iframe with a chrome extension

I'm developing a Chrome extension which will do:

  1. Access a website's iframe
  2. Retrieve some data
  3. Create a CSV file

I'm struggling on the first step. I've tried many ways to do it and have failed.

The frameset looks like this:

<frameset rows="72,*,0,0,50" onunload="finalize()" frameborder="no" border="0" framespacing="0">
    <frame name="Nav" src="navigation.jsp" scrolling="no" noresize="noresize"/>
    <frame name="Trans" src="summary.do" marginheight="0" marginwidth="0" onload="javascript:logTrack();"/>
</frameset>

My last attempt was:

popup.html

<html>
  <head><script src="jquery.js"></script></head>
  <body>
    <button id="test">TEST!</button>
    <script src="popup.js"></script>
  </body>
</html>

popup.js

document.getElementById("test").addEventListener('click', () => {
    console.log("Popup DOM fully loaded and parsed");

    function modifyDOM() {
        //You can play with your DOM here or check URL against your regex
        console.log('Tab script:');
        //console.log(document.body);

        // Find the frame
        var frame = $(document).find("frame[name='Trans']")[0];
        // Callback once frame's internals are loaded
        $(frame).load(function() {
          console.log('Found!');
        });

        return document.body.innerHTML;
    }

    //We have permission to access the activeTab, so we can call chrome.tabs.executeScript:
    chrome.tabs.executeScript({
        code: '(' + modifyDOM + ')();' //argument here is a string but function.toString() returns function's code
    }, (results) => {
        //Here we have just the innerHTML and not DOM structure
        console.log('Popup script:')
        console.log(results[0]);
    });
});

I'm getting the error Uncaught ReferenceError: $ is not defined (probably JQuery is not being loaded properly)

Upvotes: 1

Views: 1087

Answers (1)

Eejdoowad
Eejdoowad

Reputation: 1381

You're asking chrome to execute this string in the context of the page's content script:

"(function modifyDOM() {
    //You can play with your DOM here or check URL against your regex
    console.log('Tab script:');
    //console.log(document.body);

    // Find the frame
    var frame = $(document).find("frame[name='Trans']")[0];
    // Callback once frame's internals are loaded
    $(frame).load(function() {
      console.log('Found!');
    });

    return document.body.innerHTML;
})"

Content scripts live in their own isolated context, meaning they share NOTHING with the popup, the local page, the background page, or anything else.

So you're right, JQuery isn't being loaded properly - it's not being loaded at all.

What you can do is... first chrome.tab.execute JQuery, then chrome.tab.execute your script. If you go down this path, make sure you do so in the right order and right way.

I advise against going down that path. Either 1) use pure javascript with no JQuery or 2) use a module bundler like Webpack or Grunt to package JQuery and your script into a single JS file.

Another issue you'll want to watch out for is that you can't access an embedded iframe's content unless it has the EXACT SAME protocol, domains and port as the parent frame. If that's not the case, you'll have to explore executing a content script in the context of a particular frame by passing a frameId to chrome.tabs.executeScript.

Upvotes: 1

Related Questions