使用webNavigation.onCommitted将脚本注入网页

时间:2019-07-11 21:11:52

标签: javascript html browser firefox-webextensions

我想找到一种方法,一旦在Web扩展中可以使用DOM,并且在加载任何其他脚本之前,就可以注入脚本元素。

我尝试通过使用webNavigation.onCommited event来实现这一目标 应该触发when a navigation is committed. At least part of the new document has been received from the server and the browser has decided to switch to the new document.(引用先前链接的页面)。

事实是,当我注入脚本时,文档已经由浏览器解析和呈现,因此尚未定义要从网页角度引用的对象。

我仅在Firefox上进行了测试,暂时不关心其他浏览器的支持。

我建立了一个最小的,可复制的示例。整个来源都可以获取here

基本上,在后台脚本中,我注册了事件处理程序,该事件处理程序将内容脚本注入“已提交”标签:

browser.webNavigation.onCommitted.addListener(details => {
  browser.tabs.executeScript(
    details.tabId,
    {
      'file': 'inject.js',
      'runAt': 'document_start'
    })
  console.log(details)
})

在inject.js中,我创建一个脚本元素并将其附加到文档根目录:

const script = document.createElement('script')
script.src = browser.runtime.getURL('script.js')
script.onload = () => {
  console.log('injected')
}

console.log('injecting')
document.documentElement.appendChild(script)

0

script.js非常简单:

TEST=1

为了测试扩展,我建立了另一个无效的简单网页:

<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>Test</title>
    <script>
console.log('too late?', window.TEST ? 'no' : 'yes :\\')
    </script>
  </head>
</html>

我希望在控制台中看到一条日志行'太迟了?没有'。它总是碰巧为时已晚?是:\',除了少数情况,例如第一次打开网页,关闭包含该页面的选项卡并进行还原(CTRL + SHIFT + T)。刷新页面(F5,CTRL + F5等)总是导致“太晚了?是的:\'

2 个答案:

答案 0 :(得分:0)

我不确定,但是我认为问题可能出在extensionType RunAt上,而不是提交事件触发的时间:

"document_start": corresponds to loading. The DOM is still loading.

这是脚本将被最快注入的时间。因此,我认为无法实现您的目标。

答案 1 :(得分:0)

  

我想找到一种方法,一旦在Web扩展中可以使用DOM,并且在加载任何其他脚本之前,就可以注入脚本元素。

一旦DOM可用,内联脚本已经加载,远程脚本已经开始加载。使用content_scripts将其注入"document_start"

"content_scripts": [
  {
    "matches": ["*://*.mozilla.org/*"],
    "js": ["inject.js"],
     "run_at": "document_start"
  }
]

"inject.js"中添加beforescriptexecute侦听器,例如:document.addEventListener("beforescriptexecute", starting, true);(仅受Firefox支持)

然后,在脚本执行之前对其进行处理。

如果需要处理DOM,则还需要为DOMContentLoaded添加一个侦听器,例如:document.addEventListener('DOMContentLoaded', doSomething);