Firefox WebExtention executeScript runAt无知

时间:2016-11-17 11:09:05

标签: javascript firefox firefox-addon firefox-webextensions

我正在为Firefox浏览器编写小型WebExtention。事实证明,对于来自 manifest.json 与来自runAt方法的内容脚本,Firefox处理browser.tabs.executeScript属性的方式不同。

内容的script.js

console.log('content script fired!');

后台脚本 settings-script.js

function handleUpdated(tabId, changeInfo, tabInfo) {
    var pageVar = "console.log('executeScript fired!'); 
    var executing = browser.tabs.executeScript(tabId, {
        code: pageVar,
        runAt: "document_start"
    });
}

browser.tabs.onCreated.addListener(handleUpdated);
browser.tabs.onUpdated.addListener(handleUpdated);

测试page.html中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test my behaviour</title>
</head>
<body>
    <script type="text/javascript">
        console.log('start very first page script');
    </script>
</body>
</html>

的manifest.json

"permissions": [
  "activeTab",
  "storage",
  "tabs",
  "http://*/*", 
  "https://*/*",
  "file://*/*"
],
"background": {
  "scripts": ["background/settings-script.js"]
},
"content_scripts": [
  {
    "matches": ["<all_urls>"],
    "js": ["content-script.js"],
    "run_at": "document_start"
  }
],

控制台输出如下所示:

'content script fired!'
'start very first page script'
'executeScript fired!'

那么,当我以runAt以编程方式注入时,为什么Firefox会忽略我的document_idle属性并继续在tabs.executeScript()上执行脚本?

有没有我错过的东西?

1 个答案:

答案 0 :(得分:1)

  

那么,为什么当我用编程方式用tabs.executeScript()注入时,Firefox会忽略我的runAt属性并继续在document_idle上执行脚本?

没有。现在为时已晚 - 您正在与该页面竞争。

tabs.executeScript会将runAt作为最早运行脚本的机会。但是当您的executeScript实际运行时,页面已经完全加载。

考虑一下:使​​用manifest.json中定义的脚本,Chrome会提前知道某些脚本必须在页面加载之前。

另一方面,tabs.onCreated / tabs.onUpdated在创建/更新开始后的某个时刻触发。有一个自然的处理延迟,而页面继续加载 - 它不是一个阻止事件,直到所有扩展决定做什么。当您调用executeScript API时,Chrome还需要一些时间来调整其内部机制。

你的琐碎页面已经结束了。对于缓慢加载的页面,您可能会看到差异,但不会显示您作为测试显示的页面。

正确的解决方案,在运行时决定哪些脚本提前并不存在。理论上,chrome.declarativeContent.RequestContentScript应该允许这样做 - 但即使在稳定的Chrome版本中也不支持它,当然也不支持Firefox。

如果您需要在document_start脚本中实现某些条件逻辑,那么它非常困难 - 您无法异步执行任何操作,因此chrome.storage和Messaging无法提供帮助。< / p>