Firefox WebExtention executeScript runAt 无知

Firefox WebExtention executeScript runAt ignorance

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

内容-script.js:

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

后台脚本设置-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!'

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

有什么我遗漏的吗?

So, why does Firefox ignore my runAt property and keep executing script on document_idle when I inject it with tabs.executeScript() programmatically?

没有。太晚了 - 您正在与页面赛跑。

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

考虑一下:使​​用 manifest.json 中定义的脚本,Chrome 预先知道某些脚本必须先于页面加载。

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

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


一个适当的解决方案来决定,在运行时间,预先包含什么脚本并不真正存在。 chrome.declarativeContent.RequestContentScript 在理论上应该允许这样做 - 但即使在稳定的 Chrome 构建中也不支持它,当然在 Firefox 中也不支持。

如果您需要在 document_start 脚本中实现一些条件逻辑,这非常困难 - 您不能异步执行任何操作,因此 chrome.storage 和消息传递无济于事。