Chrome瀏覽器擴展插件教程:從MV2遷移到Manifest V3
Chrome Web Store於2021年1月已經開始接受Manifest V3擴展的提交。如果你還在使用MV2版本,那麼一定要在官方棄用之前,儘快更新到MV3版本。
Chrome瀏覽器從88版本開始支持MV3啦(即Manifest Version 3),目前查看官方文檔時默認已經是MV3版本。
我們這篇文章主要了解3個問題
1、MV2的棄用時間表
2、瞭解MV3的新特性
3、如何將MV2遷移到MV3
一、Manifest V2棄用時間表
此圖表指定了棄用Manifest V2(MV2)的時間表
- 2022年1月份開始不接受新的MV2版本(除了”私人”可見類型),開發者可以更新已經存在的MV2擴展插件
- 2022年6月份不接受新的MV2版本,開發者可以更新已經存在的MV2擴展插件
- 2023年1月份開始,開發者不能更新MV2的擴展插件,MV2也不能在Chrome瀏覽器運行(除了個別的企業版)
- 2023年6月份MV2版本將不能在Chrome瀏覽器運行
二、Manifest V3新特性
Manifest V3是十年前推出擴展平台以來最大的轉變之一。Manifest V3的新的擴展規範將在安全性、私密性和性能方面得到增強;也可以使用Manifest V3中採用的更現代的開放網絡技術,比如Service Worker和Promises。並會逐步淘汰Manifest V2。
MV3新特性概要
declarativentrequest API
三、如何將MV2遷移到MV3
1、修改manifest.json
1)manifest.json版本號
顯而易見第一步需求修改 manifest.json 文件
{ ..., "manifest_version": 3, ... }
2)Host Permissions
在Manifest V2中,有兩種方法為你的api或任何主機獲得權限,要麼在 permissions
數組或 optional_permissions
數組。
在Manifest V3中,所有主機權限現在都單獨存在一個新數組中,該數組的鍵為 host_permissions
。主機權限不再與其他權限一起添加。
MV2
{ ..., "permissions": [ "http://tahub.app/*" ], ... }
MV3
{ ..., "host_permissions": [ "http://tahub.app/*" ], ... }
3)Background Scripts
Manifest V3用Service Worker替換了 background scripts。
MV2 Background對象目前看起來是這樣的:
{ ..., "background": { "scripts": ["assets/js/background.js"], "persistent": false }, ... }
我們需要做的是把 script
數組的鍵改為 service_worker
,替換多個background pages或scripts。所以,它應該是這樣的:
{ ..., "background": { "service_worker": "assets/js/background.js" }, ... }
注意,我們不再需要添加 persistent
了。
4)Actions
Actions
過去是 browser_action
和 page_action
,但現在它們在Manifest V3中統一為 Actions
。這是因為隨着時間的推移,分開他們變得沒有必要。
MV2
// Manifest V2 // manifest.json { "browser_action": { … }, "page_action": { … } } // background.js chrome.browserAction.onClicked.addListener(tab => { … }); chrome.pageAction.onClicked.addListener(tab => { … });
MV3
// Manifest V3 // manifest.json { "action": { … } } // background.js chrome.action.onClicked.addListener(tab => { … });
5)Content Security Policy (CSP)
你需要改變它從一個String(在Manifest V2)到一個Object(在Manifest v3)。
MV2
// Manifest V2 "content_security_policy": "..."
MV3
// Manifest V3 "content_security_policy": { "extension_pages": "...", "sandbox": "..." }
6)Web-Accessible Resources
將 web_accessible_resources
數組更改為一個詳細描述所有資源的對象,每個對象都可以映射到到一組url或擴展id。下面是V3版本的一個例子:
MV2
// Manifest V2 "web_accessible_resources": [ RESOURCE_PATHS ]
MV3
// Manifest V3 "web_accessible_resources": [{ "resources": [RESOURCE_PATHS] }]
此外還支持其它的屬性,用於設定不同的規則: matches
、 extension_ids
、 use_dynamic_url
2、將 Background Scripts 改造成 Service Workers
首先,什麼是service worker,它和background scripts有什麼不同?
background scripts在幾乎所有擴展中都是必不可少的。允許執行一些操作或執行代碼,而不需要用户打開某個頁面或執行某些操作。這可以用於發送通知、與content scripts通信等等。後台腳本通常總是在後台運行。
Service worker在需要的時候被執行。與後台腳本不同,它們並不總是在後台運行。在最頂層,service worker將監聽器註冊到一些事件中,以允許它們稍後被執行。
從background scripts到service worker的轉換依賴於擴展中的代碼。一些擴展可能需要大量的工作,而另一些則不需要這麼多。
需要做的第一步是將以前作為background scripts文件移動到根目錄。
{ ..., "background": { "service_worker": "background.js" }, ... }
現在,讓我們看看代碼。以前的background script如下:
chrome.runtime.onMessage.addListener(function(message, sender, senderResponse){ if(message.msg === "image"){ fetch('http://some-random-api.com/img/xxx') .then(response => response.text()) .then(data => { let dataObj = JSON.parse(data); senderResponse({data: dataObj, index: message.index}); }) .catch(error => console.log("error", error)) return true; } });
基本上,我們的後台腳本使用 chrome.runtime.onMessage.addListener
來監聽一個消息,如果該消息請求一個圖片,它將向API發送一個請求,然後將數據返回給我們的content script。
這個background script實際上不需要任何額外的更改。因為service worker的後台腳本只是註冊了一個事件監聽器,並在事件發生時執行代碼,這正是service worker應該做的。
但並不是所有的擴展都是這樣的,因為有不同的情況。以下是你在background script中需要檢查和修改的內容:
1) 全局變量
以前的後台腳本總是在後台運行。如果有以下代碼:
let count = 0; chrome.runtime.onMessage.addListener( (message) => { count++; console.log(count); });
每當service worker收到一條消息時,count就會增加。一開始是0,然後是1,然後是2,以此類推。
在service worker中,這將不再有效。service worker只會在需要時運行,並在完成工作時終止。因此,上述代碼將始終在控制枱打印“1”。
在上面的例子中,計數可以在background script和content script之間來回傳遞,以獲得所需的結果。更好的方法是使用Chrome的存儲API。
2) Timers and Alarms
Timers 在後台腳本中使用沒有問題,因為它們總是在後台運行。然而,這不適用於服務工作者。你應該用 Alarms API 替換所有的計時器。
3) 訪問DOM
Service worker不能訪問windows或DOM。如果你的擴展需要,你可以使用類似 jsdom 的庫或使用chrome.windows.create和chrome.tabs.create。這取決於你的具體使用場景。
如果你的background scripts有錄製音頻或視頻,這也是需要修改的,因為這在service worker中是不可以的。
4) 創建Canvas
如果你的background scripts之前創建了畫布,你仍然可以用 offscreenenccanvas API 來做。你所要做的就是用 OffscreenCanvas
替換 document
。
MV2
let canvas = document.createElement('canvas');
MV3
let canvas = new OffscreenCanvas(width, height);
在完成這些修改之後,需要將你的background scripts 修改為service worker,在瀏覽器中重新加載你的擴展,看看它是否正常工作。
5) 執行腳本executeScript
如果你的代碼使用executeScript的code屬性執行任意字符串,有兩種方法來更改它。同時,不使用chrome.tabs.execute腳本,需要用 script
替換標籤,這樣它將是 chrome.script .executeScript
。
將代碼移植到文件
你需要將代碼的值移動到一個新文件,並使用executeScript的 file
屬性。
之前
chrome.tabs.executeScript({ code: alert("Hello, World!") });
修改為
將 alert(“Hello, World!”)
放到一個新文件(讓我們叫它 Hello - World .js
):
alert("Hello, World!");
chrome.scripting.executeScript({ file: 'hello-world.js' });
將代碼放到Function中
如果你的代碼可以放在一個函數中,可以將它移動到同一個文件中的一個函數中,然後將execute escripts的 function
屬性賦值給你創建的函數:
function greeting() { alert("Hello, World!"); } chrome.scripting.executeScript({ function: greeting });
3、其它需求檢查的
這裏有一個列表,列出了你需要在代碼中尋找的要更改的內容:
1、如果你的擴展使用 webRequest API
,它通常用於強制安裝擴展的企業設置,你需要用 declarativentrequest API 替換它。
2、如果你在內容腳本中發出任何CORS請求,請將它們移動到service worker中。
3、不再允許遠程託管代碼。你需要找到另一種方法來執行遠程託管的代碼。Chrome的文檔建議使用 配置驅動功能和邏輯 ,這個意思就是説將配置本地化,然後執行用遠程的web服務來執行。
4、請查看 API參考 ,瞭解可能正在使用的已棄用的API或方法。
好了,以上就是本篇主要內容,Manifest V3的新特性讓擴展更安全,其實長遠看是有好處的,這樣瀏覽器擴展也不會被濫用,只是之前的MV2一些用法和寫法需要做一些調整,工作量應該不會很大,逐條檢查自己產品中存在的問題,相信問題一定能夠解決,祝大家產品越做越好!