1

I'm writing a chrome extension and it has both a content.js to manipulate the current tab data as well as a popup that is generated upon execution. However, my problem is that when i make changes to the extension, I have to both reload the extension and refresh the page, otherwise it give me a "Error establishing connection, port does not exist" error. Here's my manifest.json file

{
    "manifest_version": 2,
    "name":    "extension",
    "version": "0.0",
    "offline_enabled": true,

    "content_scripts": [
        {
            "matches": [
                "*://mail.google.com/*"
            ],
            "css": ["css/jquery-ui.css"],
            "js":     ["js/jquery.js" , "js/jquery-ui.js" , "js/bootstrap.js" , "js/commons.js" , "js/content.js"],
            "run_at": "document_end"
        }
    ],

    "browser_action": {
        "default_title": "chrome",
        "default_popup": "html/popup.html"
    },
    "permissions": [
    "tabs",
    "https://*.*.*/"
    ]
}
Irtza.QC
  • 1,026
  • 2
  • 10
  • 23
  • Do you have any code in content.js that tries to connect online? – Meeh Oct 15 '15 at 11:51
  • i have a handful of API calls to a site yes. Is that whats causing the problem? – Irtza.QC Oct 15 '15 at 11:53
  • From my limited knowledge for extensions, I think that's your problem yes. API calls should be moved to background.js. Here is someone that has a similar problem: http://stackoverflow.com/questions/13637715/not-receiving-any-data-from-webpage-to-content-js-of-chrome-extension Content scripts should be used to interact with the "current" page in a tab. Like a password saver, or development/debugging extension, linter, and so on. https://developer.chrome.com/extensions/content_scripts – Meeh Oct 15 '15 at 12:00
  • forgive me if this sounds stupid to you but what if i change content.js to background.js? would the background.js still be able to grab the DOM? and if i do that, what changes would i need to change in the manifest.js? – Irtza.QC Oct 15 '15 at 12:04
  • No that doesn't sound stupid for me. But it won't be able to access the DOM. I would think a "bridge" between background and content would solve your problem. So that you should have both. Chrome supports communication between content scripts and/or the background page via chrome.runtime.sendMessage + .onMessage. But notice that the data will be JSON serialized so you can't transfer a object like jQuery. – Meeh Oct 15 '15 at 12:08
  • @Irtza.QC, so why refreshing is a problem? Also do you use `chrome.runtime.SendMessage` or `chrome.runtime.connect`? – wOxxOm Oct 15 '15 at 12:12
  • I'm using `chrome.runtime.SendMessage` the problem is the user experience, having to refresh after loading the extension would be an annoyance that I would prefer to avoid if possible. – Irtza.QC Oct 15 '15 at 12:25
  • not sure why all this chat. its fully unrelated to your question. what you ask is vy design and all extensions behave that way. you need to reload the extension and refresh t.he page whenevee you make changes. – Zig Mandel Oct 15 '15 at 12:43
  • I've found the answer posted here is a good workaround: https://stackoverflow.com/a/25844023/1394731 – theicfire Jun 28 '20 at 04:46

1 Answers1

3

This is normal behaviour. When you make changes in your extension you have to reload it. But when you reload extension, all existing content script injections lost their connections with background page. More than that, if you try to reconnect on port.onDisconnected.addListener you will get an exception, for security reasons, because new background process will not be able to recognize its previous content script injections.

When I run into this issue I came up with this solution:

reconnect();

function reconnect() {

    var port = chrome.runtime.connect({
        name: 'injection'
    });

    port.onMessage.addListener(handleMessage);
    port.onDisconnect.addListener(function() {
        console.log('bg script disconnected');
        setTimeout(function() {
            try {
                reconnect();
            } catch (e) {
                location.href = location.href;
            }
        }, 1000);
    });
}

function handleMessage() {
}

I know, this is nothing just automatic page reloading, but there's no other way to reconnect from previous content script injection - updated extension code must be injected again in order to be able to connect to background script.

Anatoliy
  • 29,485
  • 5
  • 46
  • 45
  • i tried to use this to automatically reload the page however it did nothing? – Irtza.QC Oct 16 '15 at 12:11
  • If you see "bg script disconnected" in your console logs, that probably means it takes more than 1 second to spin up the extension. You could try to add console.log when you connect in order to see what is actually going on. – Anatoliy Oct 16 '15 at 12:49