declarativeNetRequest API 打造一個 adblocker(也寫作 ad blocker 或 content blocker)。你宣告比對規則,瀏覽器就會在請求離開網路堆疊前原生封鎖它們。
你會做出什麼
為什麼 MV3 取代了阻斷式 webRequest
Manifest V2 的廣告封鎖器註冊阻斷式webRequest 監聽器。每個請求都要暫停,等擴充功能的 JavaScript 決定它的命運。Manifest V3 基於效能與隱私因素移除了這個模型。改用 declarativeNetRequest 後,瀏覽器自己評估你的規則。你的程式碼從不佔據請求路徑,也從不為了封鎖而讀取請求內容。
代理式的使用情境,例如把所有流量導向另一台伺服器,請改用 proxy API 而不是請求規則。
Manifest
封鎖與允許規則不需要 host permissions。重新導向規則與標頭規則需要受影響網站的 host permissions。manifest.json
rule_resources 引用的規則集檔案,並隨建置輸出一起發出。
靜態規則
靜態規則放在rules.json,會在擴充功能載入時載入。
rules.json
||domain^ 過濾語法會比對一個網域及其所有子網域。
封鎖整個頁面
在resourceTypes 裡寫上 main_frame 的規則會封鎖頂層導覽,而不只是子資源:
rules.json
- Chrome 會把分頁換成它自己的封鎖頁,顯示 “This page has been blocked by an extension” 與代碼
ERR_BLOCKED_BY_CLIENT。主控台裡沒有任何輸出。 - Firefox 會取消這次導覽,分頁保留先前的頁面。沒有錯誤頁,也沒有主控台項目。
dist/<browser>/declarative_net_request/ 並改寫 manifest 裡的路徑,所以依上面 manifest 的寫法引用它即可。
本節與下一節的行為是在 Chrome 155 與 Firefox 158 上、使用 Extension.js 4.1.33 量測的。
把被封鎖的頁面重新導向到擴充功能內的頁面
把block 動作換成 redirect,指向隨擴充功能一起出貨的頁面:
rules.json
public/blocked.html。Extension.js 會把 public/ 複製到輸出根目錄,所以 /blocked.html 不必在 manifest 裡登記就能解析。
重新導向需要的權限比封鎖多,而且兩個瀏覽器不一樣:
- Chrome 需要涵蓋該網站的主機權限。沒有它,規則就是靜默的空操作:頁面正常載入,規則集仍顯示已啟用,主控台裡什麼都沒有。對於指向擴充功能頁面的
main_frame重新導向,Chrome 不需要web_accessible_resources。 - Firefox 既需要主機權限,也需要把頁面列進
web_accessible_resources。缺少web_accessible_resources項目時,導覽會以NS_ERROR_DOM_BAD_URI失敗,分頁停在原處。缺少主機權限時則和 Chrome 一樣是靜默的空操作。
action 範本把 Firefox 建置為 Manifest V2,那裡的主機權限寫在 permissions 中,web_accessible_resources 是字串清單。帶前綴的鍵會在其目標上取代同名的一般鍵,所以 Firefox 的清單要再寫一次 declarativeNetRequest。藉由瀏覽器專屬欄位,一份 manifest 同時涵蓋兩個瀏覽器:
manifest.json
firefox: 鍵,在一般的 web_accessible_resources 下使用物件形式 [{ "resources": ["blocked.html"], "matches": ["<all_urls>"] }]。兩個瀏覽器都接受。
動態規則
動態規則用於在執行階段變動的過濾條件,例如使用者自行加入的封鎖清單項目。重新加入規則前先移除該規則 id,讓更新保持冪等。background.js
declarativeNetRequest 參考文件確認目前的限制。
在徽章上統計已封鎖的請求
一個呼叫就能把 action 徽章變成各分頁的規則命中計數器。background.js
getMatchedRules 自行讀取命中的規則,需加上 declarativeNetRequestFeedback 權限。
執行
在編輯manifest.json 之前,先知道 manifest 變更需要重新啟動開發伺服器。參考 開發更新行為。
Firefox 注意事項
- Firefox 在 Manifest V3 支援
declarativeNetRequest。 - Firefox 不支援
setExtensionActionOptions,因此徽章計數器僅限 Chromium。 - Firefox 在 Manifest V3 仍允許阻斷式
webRequest,Chrome 則把它保留給政策安裝。 - 當兩個目標出現分歧時,使用 瀏覽器專屬 manifest 欄位。
從範本開始
action 範本附帶一個 background script 加上工具列 popup,是封鎖器 UI 的好基礎。
最佳實務
- 靜態規則放在
rules.json,動態規則保留給使用者的選擇。 - 給每個動態規則一個穩定的 id,讓移除保持可預期。
- 把
resourceTypes限定在你要封鎖的類型,而不是所有類型。 - 優先使用封鎖與允許規則,它們不需要 host permissions。
- 在發佈過濾條件更新前,用真實頁面測試規則。
後續步驟
- 在 攔截網路請求 觀察流量而不封鎖它。
- 用 安全檢查清單 稽核你的權限面。
- 在 Manifest V3 概念 檢視 background 模型。

