3

I am trying to create a chrome extension, but for some reasons, sometimes, the chrome.runtime object seems incomplete, and a lot of methods are missing (including onMessage, which is the one I want).

It seems sometimes it works, sometimes not. I assumed it may be a time related issue, but I don't understand why I can't simply create a message listener on background?

My background script:

setTimeout(function () {
    console.log("gogo!");
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            console.log(sender.tab ?
                        "from a content script:" + sender.tab.url :
                        "from the extension");
            if (request.type == "tab") {
                console.log("tab!");
                sendResponse({status: "ok"});
            }
        }),
    2
});

Where "chrome.runtime.onMessage" is undefined.

Thanks!

Edit2: I have built a much simpler prototype, and it's failing again. Now I am really confused. Here is what I have:

$tree
.
├── manifest.json
├── src
│   ├── background.html
│   ├── background.js
│   └── test.js
└── vendor
    └── jquery.js

2 directories, 5 files

manifest.json file:

{
    "manifest_version": 2,

    "name": "test",
    "description": "test",
    "version": "1.0",
    "author": "test",

    "homepage_url": "http://www.test.com",

    "content_scripts": [
        {
            "run_at" : "document_idle",
            "matches": ["https://www.google*"],
            "js": ["vendor/jquery.js", "src/test.js"]
        }
    ],

    "background": {
        "page": "src/background.html",
        "persistent": false
    },

    "permissions": [
        "tabs",
        "https://www.google*"
    ]
}

background.html file:

<script src="../vendor/jquery.js"></script>
<script src="background.js"></script>

background.js file:

function run () {
    console.log("gogo!");
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            console.log(sender.tab ?
                        "from a content script:" + sender.tab.url :
                        "from the extension");
            if (request.type == "tab") {
                console.log("tab!");
                sendResponse({status: "ok"});
            }
        });
}

run();

test.js file:

'use strict';

run();

function run() {
    var url = window.location.href;

    // Error if no URI
    if (!url) {
        return 1;
    }

    var uriRe = /https:\/\/www\.google.*/;
    var reParse = uriRe.exec(url);
    if (!reParse) {
        return 2;
    }

    chrome.runtime.sendMessage({type: "tab"}, function(response) {
        console.log(response);
    });
}

I am using Chrome 49.0.2623.112 (64-bit) on OSX.

Edit: Here is a screenshot of what happens the times it fails:

Failure screenshot

I want to precise again that it doesn't fail all the time (maybe 50% of the time?), which makes it even more weird and makes me believe there is a kind of "race" condition somewhere I am not aware of.

termux
  • 331
  • 3
  • 14
  • Why are you wrapping it in a timeout? – Daniel Herr Apr 15 '16 at 19:29
  • Is your background page an event page? ("persistent": false set) If so, you shouldn't call setTimeout. If it is an event page check out the [docs](https://developer.chrome.com/extensions/event_pages) because there are some things to be aware of. – Michael Updike Apr 16 '16 at 01:14
  • @DanielHerr It was just a test as I was suspecting a time related issue. It seems it was working better with a timeout, but I'm not sure about it at all. – termux Apr 18 '16 at 04:20
  • @MichaelUpdike Thanks for the advice. I tried to set "persistent": false and the problem is still the same. I tried to set "persistent": true for testing, and it is still the same. – termux Apr 18 '16 at 04:21
  • 1
    Do you have any devtools extension running? I know of a bug where the extension runtime page was incorrectly classified as a non-extension page, which is fixed in Chrome 51 (currently Chrome Beta) - https://crbug.com/544182 – Rob W Apr 18 '16 at 09:38
  • @RobW Thanks, it has worked! I am not sure what happened, but after disabling all my extensions and re-activating them, now it works without any problem. Seems like a bug from Chrome ... anyway, thanks again :) – termux Apr 18 '16 at 10:57
  • In my case (not OP's case), it was due to, the testing html page I have is using script injection for `main.js`. But at the same time, html page *manually refer to* the script by `` -- I forgot to *remove* this line... – Nor.Z May 29 '23 at 15:24

4 Answers4

5

Problem solved: I had to disable, then re-enable all my other extensions. Seems like a bug from Chrome.

termux
  • 331
  • 3
  • 14
0

click the top and set the console in extension environmint

enter image description here

the background just run once.you should run more to check the resutl

this is my code it wroks well:

chrome.tabs.onUpdated.addListener(
 function(tabId,info,tab){
  if(info.status=="complete")
   console.log("complete")
  chrome.tabs.sendMessage(tabId, {greeting: "inupdate"}, function(response) {
   console.log(response);
  });
 }
)
0

I just encountered the same problem. Typing "chrome.runtime" on the console and expanding the resulting object by clicking on the little triangle showed that it had only 1 function instead of many. In particular, chrome.runtime.onMessage was undefined.

On the page chrome://extensions I clicked the "Remove" button on the extension I was working on. I then clicked "Load unpacked" near the top of the page and selected the directory with my extension. After that, chrome.runtime was fully populated, and my extension ran correctly. I have no idea why that worked.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 21 '22 at 06:45
-1

I think it has to do with the timeout function you are using, Google already has something called alarms which helps to schedule code to run periodically or at a specified time.

https://developer.chrome.com/apps/alarms

Try that instead of timeout

thepiyush13
  • 1,321
  • 1
  • 8
  • 9
  • Thanks, but it seems the timeout was just a test, I don't actually need it, as what I'm trying to do is an event listener. – termux Apr 18 '16 at 04:21