tabs.executeScript - how can I tell if content script was being injected?

非 Y 不嫁゛ 提交于 2019-12-11 14:16:10

问题


I inject content scripts into websites programmatically using browser.tabs.executeScript. This will return a Promise, but in case of its rejection there seems to be no way of differentiating between the following 2 cases:

  1. The content script couldn't be injected (i.e. for missing host permission)
  2. An error occured on script updateparsingend:update(but the script was being injected)

I'm only interested in whether the script was being injected or not.

The argument passed to the catch is an Error object. catch(e => console.log(e.toString()) will output the error message, which can either be a reason for an injection failure (i.e. Missing host permission) or an error that occurred updatereading the scriptend:update.

    browser.tabs.executeScript(tabId, {
        file: '../path/to/content-script.js',
        frameId: 0,
        runAt: 'document_idle'
    })
        .catch(e => console.log(e.toString()));

So, for example if the content script is as follows:

    window.document.body.addEventListener('click', e => console.log('clicked body'), false);
    bla.bla();

then the Promise is being rejected, since bla.bla is undefined - but the script was being injected successfully.

In case the content script couldn't be injected I'd like to notify the user with the corresponding error message. But when an error occurred updatethat is unrelated to whether the script could be injectedend:update, while the script was being injected, I don't want to notify the user, but handle it silently. Is there a way to differentiate between those 2 cases?

EDIT: I came up with an indirect solution: In case the returned Promise was rejected I try to send a message to the content script. If this fails then the background script "knows" that no content script was being injected -> notify user.


回答1:


This is how the Promise works....

browser.tabs.executeScript(tabId, {
  file: '../path/to/content-script.js',
  frameId: 0,
  runAt: 'document_idle'
})
.catch(e => console.log(e.toString()));

catch in above will catch errors if the tabs.executeScript failed to inject. It may also show some errors when parsing the file in order to inject, if the JS file has parsing errors (invalid JS). It has nothing to do with what '../path/to/content-script.js' will be doing afterwards.

So once it was injected, then above Promise is fulfilled.

If the injected script has a sync return, then it can be received by the tabs.executeScript via then() e.g.

browser.tabs.executeScript(tabId, {
  file: '../path/to/content-script.js',
  frameId: 0,
  runAt: 'document_idle'
})
.then(result => {})
.catch(e => console.log(e.toString()));

In case of async functions such as .addEventListener which will happen later, then is nothing returned to tabs.executeScript

To catch errors in the content scripts, you can generate the error message within the content script or send a message to background script i.e. sendMessage & onMessage.addListener

tabs.executeScript()
A Promise that will be fulfilled with an array of objects, representing the result of the script in every injected frame.
The result of the script is the last evaluated statement, which is similar to what would be output (the results, not any console.log() output) if you executed the script in the Web Console. For example, consider a script like this:

var foo='my result';foo;
browser.tabs.executeScript(tabId, {
  file: '../path/to/content-script.js',
  frameId: 0,
  runAt: 'document_idle'
})
.then(result => {
  // result is returned by the Promise
  if (result === []) { 
    // it was fine but there was nothing to return
  }
  else if (result[0]) {
    // result[0] is return from the promise
  }
})
.catch(e => console.log(e.toString()));

Now if you want a return (it must be sync or else you have to tie it to another Promise), return something from '../path/to/content-script.js'



来源:https://stackoverflow.com/questions/56913671/tabs-executescript-how-can-i-tell-if-content-script-was-being-injected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!