首頁  >  問答  >  主體

重新註入內容腳本:Chrome擴充功能升級或安裝後的必要步驟

<p>在安裝或升級我正在開發的Chrome擴充功能後,內容腳本(在清單中指定)不會重新註入,因此需要刷新頁面才能使擴充功能正常運作。有沒有辦法強制重新註入腳本? </p> <p>我相信我可以透過以程式設計方式將它們從清單中移除,然後在後台頁面處理要注入的頁面來再次注入它們,但這不是一個好的解決方案。 </p> <p>我不想自動刷新用戶的標籤頁,因為這可能會丟失一些資料。 Safari在安裝或升級擴充功能時會自動刷新所有頁面。 </p>
P粉066224086P粉066224086423 天前525

全部回覆(2)我來回復

  • P粉807239416

    P粉8072394162023-08-25 11:24:31

    唯一的方法強制注入內容腳本而不刷新頁面是透過程式註入。

    您可以使用Chrome瀏覽器的標籤API取得所有標籤,並向它們注入程式碼。 例如,您可以將一個版本號儲存在本機儲存中,並在每次檢查背景頁中的版本號是否過舊時(如果是),您可以取得所有活動標籤並透過程式註入您的程式碼,或任何其他可以確保擴充功能已更新的解決方案。

    使用以下程式碼取得所有標籤:
    chrome.tabs.query

    並向所有頁面注入您的程式碼
    chrome.tabs.executeScript(tabId, {file: "content_script.js"});

    回覆
    0
  • P粉158473780

    P粉1584737802023-08-25 00:54:45

    有一種方法可以在升級後使內容腳本重的擴充功能繼續正常工作,並在安裝後立即使其生效。

    安裝/升級

    安裝的方法是簡單地遍歷所有視窗中的所有標籤,並在具有匹配URL的標籤中以編程方式註入一些腳本。

    ManifestV3

    manifest.json:

    "background": {"service_worker": "background.js"},
    "permissions": ["scripting"],
    "host_permissions": ["<all_urls>"],
    

    這些host_permissions應與內容腳本的matches相同。

    background.js:

    chrome.runtime.onInstalled.addListener(async () => {
      for (const cs of chrome.runtime.getManifest().content_scripts) {
        for (const tab of await chrome.tabs.query({url: cs.matches})) {
          chrome.scripting.executeScript({
            target: {tabId: tab.id},
            files: cs.js,
          });
        }
      }
    });
    

    這是一個簡化的範例,不處理框架。您可以使用getAllFrames API並自行匹配URL,請參閱匹配模式的文件。

    ManifestV2

    顯然,您必須在manifest.json中聲明的background pageevent page腳本中執行此操作:

    "background": {
        "scripts": ["background.js"]
    },
    

    background.js:

    // Add a `manifest` property to the `chrome` object.
    chrome.manifest = chrome.runtime.getManifest();
    
    var injectIntoTab = function (tab) {
        // You could iterate through the content scripts here
        var scripts = chrome.manifest.content_scripts[0].js;
        var i = 0, s = scripts.length;
        for( ; i < s; i++ ) {
            chrome.tabs.executeScript(tab.id, {
                file: scripts[i]
            });
        }
    }
    
    // Get all windows
    chrome.windows.getAll({
        populate: true
    }, function (windows) {
        var i = 0, w = windows.length, currentWindow;
        for( ; i < w; i++ ) {
            currentWindow = windows[i];
            var j = 0, t = currentWindow.tabs.length, currentTab;
            for( ; j < t; j++ ) {
                currentTab = currentWindow.tabs[j];
                // Skip chrome:// and https:// pages
                if( ! currentTab.url.match(/(chrome|https):\/\//gi) ) {
                    injectIntoTab(currentTab);
                }
            }
        }
    });
    

    歷史趣聞

    在古老的Chrome 26及更早版本中,內容腳本可以恢復與後台腳本的連線。這在2013年修復http://crbug.com/168263。您可以在此答案的早期版本中看到此技巧的範例。

    回覆
    0
  • 取消回覆