4

I am developing a Google Chrome Extension which has a content-script, a background page, a settings page and a popup page. I learnt the hard way that though the content-script loads on the Chrome Web Store, the onMessage listeners are never invoked.

I can consistently break at the point where I am executing chrome.extension.onMessage.addListener, but the listener is never invoked. Therefore when I execute chrome.tabs.sendMessage from the background or popup pages, the responseCallback function never gets invoked - i.e. the logic inside the responseCallback never executes. Chrome doesn't even treat this like an error scenario - it accepts the request, but goes silent thereafter.

If it had treated this as an error case (as with attempting to message a chrome:// page) then the responseCallback would've been invoked with a undefined response argument - and that would cause my error-handling code to execute... but no such luck.

I could add special behavior in my code for http(s)://chrome.google.com/webstore/*, but was hoping that there was a more official way of finding pages that were barred from execution. Would appreciate any pointers there.

I found a great post here, but it doesn't have a programmatic API, hence this question.

I am already aware that the Chrome webstore and chrome:// URLs are special cases. However, per my investigation, the behavior on chrome:// URLs is different than on the Chrome Web Store. On chrome:// URLs, my content-script appears to not load at all and the sendMessage's responseCallback function gets invoked with a null/undefined response object. That is the API's official way of signalling an error and it works fine for me.

My issue is with being able to programmatically detect the errors like those experienced with the Chrome Web Store without having to hardcode the URLs (the URLs could change with time).

Thanks in advance for your responses.

Community
  • 1
  • 1

2 Answers2

2

How about adding a listener for chrome.webNavigation.onCompleted in the background script? When a new page is loaded, send a special "ping" message to the tab, and use chrome.extension.onMessage to receive and respond to the ping in your content script. If the content script doesn't respond then you know that it isn't running on that page.

Matthew Gertner
  • 4,487
  • 2
  • 32
  • 54
  • Hi Matthew, Thank you for reading, understanding and responding to my question. Yes, your approach should work. My current code employs that technique - i.e. if the page didn't respond, then the content-script isn't there (or something went wrong). Even in general it is good to have one part of the code continue to work even if another failed. However, if there was a programmatic way to filter out the problem pages (e.g. all chrome:// URLs), then I would be able to provide better tool-tips/message to the end-user explaining why the UI was missing some features. Thanks again. – user1801766 Nov 07 '12 at 04:23
  • How exactly do you want to update the UI? I don't understand why pinging the page isn't a "programmatic way" to accomplish what you want. – Matthew Gertner Nov 07 '12 at 12:00
  • Sorry, I should've said 'API' instead of 'programmatic way'. What I was hoping for, is a chrome.* API that I could call with the URl (or tab-id) as argument, and it would tell me whether or not the page allowed content scripts to run. In that case I won't even issue the 'ping' but instead display a message on the UI explaining that the page had restricted permissions. I've looked and looked, but found no suitable chrome.* API. I guess there isn't any. – user1801766 Nov 08 '12 at 07:22
  • I've edited the title to say "chrome.* API" instead of "programmatic way". – user1801766 Nov 08 '12 at 07:43
  • Yeah, in that case the answer is "no". :-) – Matthew Gertner Nov 08 '12 at 15:22
  • I suppose so. Thanks for the dialogue anyway. – user1801766 Nov 08 '12 at 22:30
0

You could try running chrome.tabs.executeScript to see if you're allowed scripting in that domain.

chrome.tabs.executeScript(tabId, {code: ""}, function() {
  if(chrome.runtime.lastError) {
    // Something went wrong, perhaps no rights
  } else {
    // Scripting allowed
  }
});
Xan
  • 74,770
  • 16
  • 179
  • 206