Javascript Google chrome扩展:如何在页面重新加载后立即注入脚本?

Javascript Google chrome扩展:如何在页面重新加载后立即注入脚本?,javascript,google-chrome,google-chrome-extension,background-process,Javascript,Google Chrome,Google Chrome Extension,Background Process,我有一个定期重新加载当前选项卡的后台脚本 var code = 'window.location.reload();'; chrome.tabs.executeScript(my_active_tab, {code: code}); 每次重新加载页面后,我都会立即插入另一个脚本 chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab){ if (changeInfo.status == 'complete')

我有一个定期重新加载当前选项卡的后台脚本

var code = 'window.location.reload();';
chrome.tabs.executeScript(my_active_tab, {code: code});
每次重新加载页面后,我都会立即插入另一个脚本

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab){
    if (changeInfo.status == 'complete') {
        chrome.tabs.executeScript(tabId, { file: "my_script.js" });
    }
});
以上是我目前掌握的代码。问题是,它可以工作,但速度太慢,因为它实际上是在加载每个图像后等待

我的目标是在DOM加载后立即执行脚本。有什么想法吗?

使用manifest.json
content\u scripts
条目和
“run\u at”:“document\u start”
使用manifest.json
content\u scripts
条目和
“run\u at”:“document\u start”
是确保内容脚本在页面存在之前被注入的唯一方法。此时注入的代码将同时找到文档。body文档。head将为null

尽可能早地使用 最早可以调用的时间是在您感兴趣的页面导航事件之后触发的事件。在此事件之前使用
tabs.executeScript()
,可能会导致您的脚本未被注入新页面而不会报告任何错误。考虑到后台脚本和加载页面过程之间时间安排的固有异步性质,此类故障可能是间歇性的,并且会受到操作系统/系统配置和加载的确切页面的影响。事实上,我所说的
webRequest.onHeadersReceived
将起作用是基于测试,而不是在Chrome源代码中进行验证。因此,可能存在一些我没有测试的角落案例

在这一点上的注入始终有效,但注入发生在页面加载方面的时间有些不一致。有时,
document.head
document.body
将为
null
(注入时总是这样)。其他时候,
document.head
document.body
将包含有效的DOM。由于背景脚本和内容处于不同的进程中,因此似乎不可能将此时间安排得更紧(即始终具有
文档.头
文档.体
):因此,本质上是异步的

使用
webNavigation.onbeforeavigate
并至少不等待关联的
webRequest.onHeadersReceived
事件太早且不起作用(未插入内容脚本)。换句话说,即使是相关事件也为时过早

显然,要尽早注入内容脚本,必须在调用
tabs.executeScript()
时指定

要在DOM存在后立即注入: 如果您想要更简单的内容,并且会导致内容脚本在页面中除主HTML文档之外的任何内容之前被注入,那么您可以使用所需URL的事件来触发您的
选项卡。executeScript()
。这将导致在主HTML文档之后立即加载注入的内容脚本。使用
webNavigation.onCommitted
更容易,因为它能够为您的事件指定筛选器。因此,只能为您感兴趣的URL调用事件侦听器

webNavigation.onCommitted
事件在主HTML页面的
webRequest.ResponseStarted
事件之后触发,但在获取任何资源之前触发(即在页面资源的任何
webRequest.BeforeRequest
事件之前)。有趣的是,它确实在声明状态为“正在加载”的
tabs.onUpdate
事件之后触发。状态为“加载”的
tabs.onUpdated
事件本身不适合触发,因为它可以出于其他原因使用相同的属性触发,但并不表示页面加载/重新加载

如果只想在重新加载页面时
制表符.executeScript()
webNavigation.onCommitted
事件侦听器接收一个属性:,该属性将基于导航的原因。其中一个值是
'reload'
,您可以使用该值仅对页面重新加载进行筛选

考虑到您对页面重新加载感兴趣,而不是加载框架,您需要确保
webNavigation
事件用于
frameId:0

以下是通过单击“重新加载此页面”按钮重新加载选项卡时发生的事件:

webNavigation.onBeforeNavigate->arg[0]={“frameId”:0,“parentFrameId”:-1,“processId”:-1,“tabId”:411,“timeStamp”:150040123978.314,“url”:http://www.example.com/"}        
webRequest.onBeforeRequest->arg[0]={“frameId”:0,“方法”:“GET”,“parentFrameId”:-1,“requestId”:“260870”,“tabId”:411,“时间戳”:150040123979.044,“键入”:“主框架”,“url”:http://www.example.com/"}        
webRequest.onBeforeSendHeaders->arg[0]={“frameId”:0,“方法”:“GET”,“parentFrameId”:-1,“requestHeaders”:[{“name”:“升级不安全请求”,“value”:“1”},{“name”:“User Agent”,“value”:“Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,像Gecko)Chrome/59.0.3071.115 Safari/537.36”},{“name”:“Accept”,“value”:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8“},{“name”:“Accept Encoding”,“value”:“gzip,deflate”},{“name”:“Accept Language”,“value”:“en-US,en;q=0.8”}],“requestId”:“260870”,“tabId”:411,“timeStamp”:150040123979.3242,“type”:“main(frame”,“url”:http://www.example.com/"}        
webRequest.onSendHeaders->arg[0]={“frameId”:0,“方法”:“GET”,“parentFrameId”:-1,“requestHeaders”:[{“名称”:“升级不安全请求”,“值”:“1”},{“名称”:“用户代理”,“值”:“Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如Gecko)Chrome/59.0.3071.115 Safari/537.36”},{“名称”:“接受”,“值”:“文本/html,appli