簡體   English   中英

Google Chrome擴展程序:頁面重新加載后如何立即注入腳本?

[英]Google chrome extension: how to inject script immediately after page reload?

我有一個后台腳本,可以定期重新加載當前選項卡。

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_scripts條目和"run_at": "document_start"

使用帶manifest.json content_scripts條目和"run_at": "document_start"確保內容腳本在頁面存在之前被注入的唯一方法。 此時注入的代碼將發現document.bodydocument.head均為null

使用tabs.executeScript()最早的注入

最早調用tabs.executeScript()是在webRequest.onHeadersReceived事件中,該事件在您感興趣的頁面導航的webNavigation.onBeforeNavigate事件之后觸發。在此事件之前使用tabs.executeScript()可能會導致您腳本不會被注入新頁面而沒有任何報告的錯誤。 鑒於后台腳本與頁面加載過程之間的時間安排具有固有的異步特性,因此此類故障可能是間歇性的,並且會受到操作系統/系統配置以及正在加載的確切頁面的影響。 實際上,我聲明webRequest.onHeadersReceived可以工作的說法是基於測試,而不是在Chrome源代碼中進行驗證。 結果,可能存在一些我沒有測試過的極端情況。

在這一點上進行注入始終是可行的,但是就頁面加載而言注入發生的時間有些不一致。 有時, document.headdocument.body將為null清單清單的manifest.json content_scripts注入帶有"run_at":"document_start"的情況總是如此)。 有時, document.headdocument.body將包含有效的DOM。 由於后台腳本和內容處於不同的進程中,因此似乎無法更嚴格地計時此時間(即,始終將document.headdocument.bodynull ):因此,它本質上是異步的。

使用webNavigation.onBeforeNavigate沒有至少等待關聯的webRequest.onHeadersReceived事件為時過早並且無法正常運行(未插入內容腳本)。 換句話說,即使關聯的webRequest.onSendHeaders事件也為時過早。

顯然,要盡早注入內容腳本,必須在對tabs.executeScript()調用中指定runAt:'document_start'

在DOM存在后立即注入: webNavigation.onCommitted

如果您想要更輕松的操作,並且會導致內容腳本先於頁面插入,而不是插入主HTML文檔,那么您只需使用webNavigation.onCommitted事件獲取所需的URL即可觸發tabs.executeScript() 這將導致注入的內容腳本在主HTML文檔之后立即加載。 使用webNavigation.onCommitted變得更容易,因為它可以為您的事件指定過濾器。 因此,您可以讓事件偵聽器僅針對您感興趣的URL進行調用。

在主HTML頁面的webRequest.ResponseStarted事件之后,但在獲取任何資源之前(即,在頁面資源的任何webRequest.BeforeRequest事件之前),都會觸發webNavigation.onCommitted事件。 有趣的是,它確實在聲明status:'loading'tabs.onUpdated事件之后tabs.onUpdated status:'loading'tabs.onUpdated事件本身並不是一個很好的觸發事件,因為它可以由於其他原因而觸發,具有相同的屬性,但並不表示頁面正在加載/重新加載。

如果只想在重新加載頁面時使用tabs.executeScript()

webNavigation.onCommitted事件偵聽器接收一個屬性: transitionType ,根據導航的原因,該屬性將是不同的值 這些值之一是'reload' ,您可以使用它來過濾僅頁面重新加載。

考慮到您對頁面重新加載感興趣,而不是對框架加載,您將需要確保webNavigation事件是針對frameId:0

這些是通過單擊“重新加載此頁面”按鈕重新加載選項卡時發生的事件:

webNavigation.onBeforeNavigate    ->  arg[0]= {"frameId":0,"parentFrameId":-1,"processId":-1,"tabId":411,"timeStamp":1500401223978.314,"url":"http://www.example.com/"}        
webRequest.onBeforeRequest        ->  arg[0]= {"frameId":0,"method":"GET","parentFrameId":-1,"requestId":"260870","tabId":411,"timeStamp":1500401223979.044,"type":"main_frame","url":"http://www.example.com/"}        
webRequest.onBeforeSendHeaders    ->  arg[0]= {"frameId":0,"method":"GET","parentFrameId":-1,"requestHeaders":[{"name":"Upgrade-Insecure-Requests","value":"1"},{"name":"User-Agent","value":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like 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":1500401223979.3242,"type":"main_frame","url":"http://www.example.com/"}        
webRequest.onSendHeaders          ->  arg[0]= {"frameId":0,"method":"GET","parentFrameId":-1,"requestHeaders":[{"name":"Upgrade-Insecure-Requests","value":"1"},{"name":"User-Agent","value":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like 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":1500401223979.538,"type":"main_frame","url":"http://www.example.com/"}        
webRequest.onHeadersReceived      ->  arg[0]= {"frameId":0,"method":"GET","parentFrameId":-1,"requestId":"260870","responseHeaders":[{"name":"Content-Encoding","value":"gzip"},{"name":"Accept-Ranges","value":"bytes"},{"name":"Cache-Control","value":"max-age=604800"},{"name":"Content-Type","value":"text/html"},{"name":"Date","value":"Tue, 18 Jul 2017 18:07:03 GMT"},{"name":"Etag","value":"\"359670651\""},{"name":"Expires","value":"Tue, 25 Jul 2017 18:07:03 GMT"},{"name":"Last-Modified","value":"Fri, 09 Aug 2013 23:54:35 GMT"},{"name":"Server","value":"ECS (rhv/818F)"},{"name":"Vary","value":"Accept-Encoding"},{"name":"X-Cache","value":"HIT"},{"name":"Content-Length","value":"606"}],"statusCode":200,"statusLine":"HTTP/1.1 200 OK","tabId":411,"timeStamp":1500401224072.296,"type":"main_frame","url":"http://www.example.com/"}        
---^^^^^^^^^^^^^^^^^^^^^^^^^-Earliest tabs.executeScript() injection is in the handler for the webRequest.onHeadersReceived event.
webRequest.onResponseStarted      ->  arg[0]= {"frameId":0,"fromCache":false,"ip":"93.184.216.34","method":"GET","parentFrameId":-1,"requestId":"260870","responseHeaders":[{"name":"Content-Encoding","value":"gzip"},{"name":"Accept-Ranges","value":"bytes"},{"name":"Cache-Control","value":"max-age=604800"},{"name":"Content-Type","value":"text/html"},{"name":"Date","value":"Tue, 18 Jul 2017 18:07:03 GMT"},{"name":"Etag","value":"\"359670651\""},{"name":"Expires","value":"Tue, 25 Jul 2017 18:07:03 GMT"},{"name":"Last-Modified","value":"Fri, 09 Aug 2013 23:54:35 GMT"},{"name":"Server","value":"ECS (rhv/818F)"},{"name":"Vary","value":"Accept-Encoding"},{"name":"X-Cache","value":"HIT"},{"name":"Content-Length","value":"606"}],"statusCode":200,"statusLine":"HTTP/1.1 200 OK","tabId":411,"timeStamp":1500401224072.5032,"type":"main_frame","url":"http://www.example.com/"}        
webRequest.onCompleted            ->  arg[0]= {"frameId":0,"fromCache":false,"ip":"93.184.216.34","method":"GET","parentFrameId":-1,"requestId":"260870","responseHeaders":[{"name":"Content-Encoding","value":"gzip"},{"name":"Accept-Ranges","value":"bytes"},{"name":"Cache-Control","value":"max-age=604800"},{"name":"Content-Type","value":"text/html"},{"name":"Date","value":"Tue, 18 Jul 2017 18:07:03 GMT"},{"name":"Etag","value":"\"359670651\""},{"name":"Expires","value":"Tue, 25 Jul 2017 18:07:03 GMT"},{"name":"Last-Modified","value":"Fri, 09 Aug 2013 23:54:35 GMT"},{"name":"Server","value":"ECS (rhv/818F)"},{"name":"Vary","value":"Accept-Encoding"},{"name":"X-Cache","value":"HIT"},{"name":"Content-Length","value":"606"}],"statusCode":200,"statusLine":"HTTP/1.1 200 OK","tabId":411,"timeStamp":1500401224074.0261,"type":"main_frame","url":"http://www.example.com/"}        
tabs.onUpdated                    ->  arg[0]= 411 :: arg[1]= {"status":"loading","url":"http://www.example.com/"} :: arg[2]= {"active":true,"audible":false,"autoDiscardable":true,"discarded":false,"height":902,"highlighted":true,"id":411,"incognito":false,"index":1,"mutedInfo":{"muted":false},"pinned":false,"selected":true,"status":"loading","title":"www.example.com","url":"http://www.example.com/","width":1282,"windowId":10}    
tabs.onZoomChange                 ->  arg[0]= {"newZoomFactor":1,"oldZoomFactor":1,"tabId":411,"zoomSettings":{"mode":"automatic","scope":"per-origin"}}        
webNavigation.onCommitted         ->  arg[0]= {"frameId":0,"processId":107,"tabId":411,"timeStamp":1500401224079.4019,"transitionQualifiers":[],"transitionType":"reload","url":"http://www.example.com/"}
--->>Here is where you can tell it's a reload --------------------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^
history.onVisited                 ->  arg[0]= {"id":"42","lastVisitTime":1500401224077.579,"title":"Example Domain","typedCount":1,"url":"http://www.example.com/","visitCount":12}        
tabs.onUpdated                    ->  arg[0]= 411 :: arg[1]= {"title":"Example Domain"} :: arg[2]= {"active":true,"audible":false,"autoDiscardable":true,"discarded":false,"height":902,"highlighted":true,"id":411,"incognito":false,"index":1,"mutedInfo":{"muted":false},"pinned":false,"selected":true,"status":"loading","title":"Example Domain","url":"http://www.example.com/","width":1282,"windowId":10}    
webNavigation.onDOMContentLoaded  ->  arg[0]= {"frameId":0,"processId":107,"tabId":411,"timeStamp":1500401224093.404,"url":"http://www.example.com/"}        
webNavigation.onCompleted         ->  arg[0]= {"frameId":0,"processId":107,"tabId":411,"timeStamp":1500401224094.768,"url":"http://www.example.com/"}        
tabs.onUpdated                    ->  arg[0]= 411 :: arg[1]= {"status":"complete"} :: arg[2]= {"active":true,"audible":false,"autoDiscardable":true,"discarded":false,"height":902,"highlighted":true,"id":411,"incognito":false,"index":1,"mutedInfo":{"muted":false},"pinned":false,"selected":true,"status":"complete","title":"Example Domain","url":"http://www.example.com/","width":1282,"windowId":10}   

注意:此信息基於我自己的測試。 我沒有找到Google提供的具有這種特定水平的文檔。 在以后的Chrome版本中,實際可行的確切時間可能會發生變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM