4
chrome.tabs.executeScript(null, { file: "jquery.js" }, function() {
chrome.tabs.update(null, {url: 'https://example.com/'});
});

above code work when I trigger when my address bar have something, means I'm at any web pages, but when I trigger when my address bar is blank, I got below error :

Unchecked runtime.lastError while running tabs.executeScript: Cannot access a chrome:// URL
    at Object.callback 
Aaron Musktin
  • 297
  • 3
  • 12
  • That's a strange logic to begin with: `executeScript`, _then_ update the tab. What are you achieving here? – Xan May 21 '15 at 08:00
  • @Xan why? I inject jquery.js and my content script, to communite with the DOM, then I want to continue to do something with my popup.js. Above code worked when my tab loaded some web pages, not when the tab is blank. – Aaron Musktin May 22 '15 at 00:52
  • Well, in your simplified code you inject jQuery only, and even then your content script only has time for synchronous operations; anything async will enter a race condition with the tab navigating away and the content script will be wiped as soon as the navigation commits. – Xan May 22 '15 at 07:24
  • @Xan I don't get the async and sync part, are you saying there might be a problem with my flow above? – Aaron Musktin May 22 '15 at 07:27
  • Yes! This is precisely what I'm saying. The content script won't persist after navigation, and has little time to do anything before. Whether it succeeds or not depends on what you're doing. – Xan May 22 '15 at 07:31
  • Yes but it's fine in my case. I just injected something to get some values of DOM elements, and pass them back to my popup.js. – Aaron Musktin May 22 '15 at 07:55
  • How do you pass them back? – Xan May 22 '15 at 08:00
  • @xan, in my content script I do like this `chrome.extension.sendRequest({message: myVar});` – Aaron Musktin May 22 '15 at 13:55
  • Then this **can fail** to process before the tab is updated. You should update the tab from the message listener, not `executeScript` callback. – Xan May 22 '15 at 13:57

1 Answers1

2
  • Normally (see also Programmatic Injection in docs) it's not possible to inject scripts into tabs with chrome:// urls because the allowed schemes are <scheme> := '*' | 'http' | 'https' | 'file' | 'ftp'.

    In Chrome before v61 it was still possible to inject into the content frame of the New Tab page, where the "blank address bar" you mentioned is represented internally as chrome://newtab/. For example the main frame has an address like this: https://www.google.com/_/chrome/newtab?espv=2&es_th=1&ie=UTF-8 (use Network panel in devtools to inspect the urls). So your manifest.json would have "permissions": ["tabs", "https://www.google.com/_/chrome/newtab*"],

  • Alternatively you can enable chrome://flags/#extensions-on-chrome-urls flag, however this is hardly useful as Chrome will show a warning each start.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • I see, seems like I have to do a validation to check whether it's chrome:// or it has some pages loaded. How to do that? get the browser URL? – Aaron Musktin May 22 '15 at 00:53
  • 2
    @AaronMusktin Do not try to guess [which URLs are unscriptable](http://stackoverflow.com/a/30261291/934239). Instead, check `chrome.runtime.lastError` in the `executeScript`'s callback and fail gracefully. – Xan May 22 '15 at 07:26
  • 1
    @AaronMusktin, You can check the URL, but even still, you would still need to handle possible errors eg when the tab is closed by the user. – Pacerier Aug 10 '17 at 04:24
  • 1
    You handle `chrome.runtime.lastError` like this: https://stackoverflow.com/a/45603880/632951 – Pacerier Aug 10 '17 at 04:24