0

I recently updated Chrome to version 55.0.2883.75. I am using a self developed Chrome Plugin to parse my HTML files wherein I use chrome.tabs.executescript to get data from background HTML page. So when I execute chrome.extension.onRequest, I save the background page's parsed data to a global variable and access it in the callback function of chrome.tabs.executescript and process it.

This was working fine till I update to Version 55.0.2883.75. How can I access the global variables in the new version ??

My Code Below :

Step 1 :

chrome.extension.onRequest.addListener(
    function (request, sender, sendResponse) {
        parser = new DOMParser();
        htmlDoc = parser.parseFromString(request.content, "text/html");

        //outputJson is a global variable which is Populated here
        outputJson = parseMyPage(outputJson, htmlDoc);


    });

Step 2:

chrome.tabs.getSelected(null, function (tab) {
    // Now inject a script onto the page
    chrome.tabs.executeScript(tab.id,{
        code: "chrome.extension.sendRequest({content: document.body.innerHTML}, function(response) { console.log('success'); });"
    }, function () {

       //my code to access global variables
if (outputJson && null != outputJson) {
    // other stuff
}

    });
}); 
Makyen
  • 31,849
  • 12
  • 86
  • 121
Ricks
  • 369
  • 3
  • 7
  • 20
  • What *exactly* is shown in the [various appropriate consoles for your extension](http://stackoverflow.com/a/38920982/3773011) when you load and execute your extension? – Makyen Dec 09 '16 at 11:08
  • Having a *manifest.json* would help here so we don't have to create one in order to test. – Makyen Dec 09 '16 at 11:21
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Dec 09 '16 at 11:47

1 Answers1

1

The way your code is designed, you are relying on the order in which two asynchronous blocks of code are executed: the extension.onRequest1 event and the callback for tabs.executeScript(). Your code requires that the extension.onRequest1 event fires before the tabs.executeScript() callback is executed. There is no guarantee that this will be the order in which these occur. If this is a released extension, it is quite possible that this was failing on users' machines, depending on their configuration. It is also possible that the code in Chrome, prior to Chrome 55, resulted in the event and callback always happening in the order you required.

The solution is to to rewrite this to not require any particular order for the execution of these asynchronous code blocks. Fortunately, there is a way to do that and reduce complexity at the same time.

You can transfer the information you desire from the content script to your background script directly into the callback of the tabs.executeScript(), without the need to explicitly pass a message. The value of the executed script is passed to the callback in an array containing one entry per frame in which the script was injected. This can very conveniently be used to pass data from a content script to the tabs.executeScript() callback. Obviously, you can only send back a single value per frame this way.

The following code should do what you desire. I hand edited this code from your code in this Question and my answer here. While the code in that answer is fully tested, the fact that I edited this only within this answer means that some errors may have crept in:

chrome.tabs.getSelected(null, function (tab) {
    // Now inject a script onto the page
    chrome.tabs.executeScript(tab.id,{
        code: "document.body.innerHTML;"
    }, function (results) {
        parser = new DOMParser();
        htmlDoc = parser.parseFromString(results[0], "text/html");
        //outputJson is a global variable which is Populated here
        outputJson = parseMyPage(outputJson, htmlDoc);
        //my code to access global variables
        if (outputJson && null != outputJson) {
            // other stuff
        }
    });
}); 

  1. extension.sendRequest() and extension.onRequest have been deprecated since Chrome 33. You should replace these anywhere you are using them with runtime.sendmessage() and runtime.onMessage.
Community
  • 1
  • 1
Makyen
  • 31,849
  • 12
  • 86
  • 121
  • This solution works Makyen !!! I think there is no need now for extension.sendRequest() and extension.onRequest() because all code is handled in the callback of chrome.tabs.executeScript(). Am I correct? – Ricks Dec 15 '16 at 10:56
  • @Ricks: Yes, that is correct. If everything you are needing from the content script is returned in the callback for `tabs.executeScript()`, then there is no need for other types of communication. – Makyen Dec 15 '16 at 15:26