tabs.executeScript-如何确定是否已注入内容脚本?

时间:2019-07-06 11:27:30

标签: firefox-addon firefox-webextensions

我使用browser.tabs.executeScript以编程方式将内容脚本注入网站。这将返回一个Promise,但是在被拒绝的情况下,似乎无法区分以下两种情况:

  1. 无法插入内容脚本(例如,缺少主机 权限)
  2. 在脚本 update 解析 end:update 时发生错误(但脚本已被注入)

我只对脚本是否被注入感兴趣。

传递给catch的参数是一个Error对象。 catch(e => console.log(e.toString())将输出错误消息,这可能是注入失败的原因(即Missing host permission),也可能是更新读取脚本结束时发生的错误:更新

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

例如,如果内容脚本如下:

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

然后,由于bla.bla未定义-但脚本已成功注入,因此Promise被拒绝。

如果无法注入内容脚本,我想用相应的错误消息通知用户。 但是当发生更新错误时,该错误与是否可以注入脚本 end:update 无关,在注入脚本时,我不想通知用户,但请保持安静。 有没有办法区分这两种情况?

编辑:我想出了一个间接解决方案:万一返回的Promise被拒绝,我尝试向内容脚本发送一条消息。如果失败,则后台脚本“知道”没有注入内容脚本->通知用户。

1 个答案:

答案 0 :(得分:0)

这是Promise的工作方式。...

browser.tabs.executeScript(tabId, {
  file: '../path/to/content-script.js',
  frameId: 0,
  runAt: 'document_idle'
})
.catch(e => console.log(e.toString()));
如果catch注入失败,上面的

tabs.executeScript将捕获错误。如果JS文件具有解析错误(无效的JS),则在解析文件以便注入时,它可能还会显示一些错误。与之后的 ../ path / to / content-script.js 无关。

因此,一旦注入,就实现了Promise以上。

如果注入的脚本具有 sync 返回,则tabs.executeScript可以通过then()接收它,例如

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

如果诸如.addEventListener之类的异步功能稍后会出现,则不会返回任何内容到tabs.executeScript

要捕获内容脚本中的错误,可以在内容脚本中生成错误消息,也可以将消息发送到后台脚本,即sendMessageonMessage.addListener

  

tabs.executeScript()
  一个承诺,将通过一系列对象来实现,   在每个注入的帧中表示脚本的结果。
  脚本的结果是最后计算的语句,即   类似于输出(结果,没有任何console.log()   输出)(如果您在Web控制台中执行了脚本)。例如,   考虑这样的脚本:

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()));

现在,如果要返回(必须同步,否则必须将其绑定到另一个Promise),请从'../ path / to / content-script.js'返回某项内容