擴充套件開發者工具
注意:本頁面介紹了 Firefox 55 中的 devtools API。雖然這些 API 基於 Chrome devtools APIs,但 Firefox 並不實現所有這些功能;因此,並非所有功能都在此處記錄。要檢視哪些功能缺失,請參閱 devtools APIs 的侷限性。
您可以使用 WebExtensions APIs 來擴充套件瀏覽器內建的開發者工具。要建立 devtools 擴充套件,請在您的 manifest.json 檔案中包含 "devtools_page" 鍵。
"devtools_page": "devtools/devtools-page.html"
此鍵的值是指向隨您的擴充套件一起打包的 HTML 檔案的 URL,這是一個特殊的擴充套件頁面,稱為 devtools 頁面。URL 必須相對於 manifest.json 檔案。
此 manifest 鍵會隱式設定 "devtools" 許可權,這會觸發 安裝時有關 devtools 的許可權警告。為避免此警告,請透過在 optional_permissions manifest 鍵中列出 "devtools" 許可權,將該功能標記為可選。設定可選許可權在更新中引入 devtools 功能時可能特別有用,因為它可防止擴充套件被停用(在 Chrome 中)或阻止更新(在 Firefox 中)。
Devtools 頁面
Devtools 頁面在瀏覽器開發者工具開啟時載入,在關閉時解除安裝。請注意,由於 devtools 視窗與單個標籤頁相關聯,因此很可能同時存在多個 devtools 視窗(因此也就有多個 devtools 頁面)。
Devtools 頁面沒有可見的 DOM,但可以使用 <script> 標籤包含 JavaScript 原始檔。原始檔必須隨擴充套件本身一起打包。這些原始檔可以訪問:
- 可透過全域性
window物件訪問的普通 DOM API - 與內容指令碼中的 WebExtension APIs 相同
- Devtools APIs
請注意,devtools 頁面無法訪問任何其他 WebExtension API,background 頁面也無法訪問 devtools API。相反,devtools 頁面和 background 頁面必須使用 runtime 訊息 API 進行通訊。這是一個示例:
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>DevTools Extension</title>
</head>
<body>
<script src="devtools.js"></script>
</body>
</html>
devtools.js 檔案將包含建立您的 dev tools 擴充套件的實際程式碼。
建立面板
Devtools 視窗託管了許多單獨的工具——JavaScript 偵錯程式、網路監視器等。頂部的標籤行允許使用者在不同工具之間切換。託管每個工具使用者介面的視窗稱為“面板”。
使用 devtools.panels.create() API,您可以在 devtools 視窗中建立自己的面板。
browser.devtools.panels
.create(
"My Panel", // title
"/icons/star.png", // icon
"/devtools/panel/panel.html", // content
)
.then((newPanel) => {
newPanel.onShown.addListener(initializePanel);
newPanel.onHidden.addListener(unInitializePanel);
});
這需要三個必需引數:面板的標題、圖示和內容。它返回一個 Promise,該 Promise 解析為代表新面板的 devtools.panels.ExtensionPanel 物件。
與目標視窗互動
開發者工具始終附加到特定的瀏覽器標籤頁。這被稱為開發者工具的“目標”或“檢查的視窗”。您可以使用 devtools.inspectedWindow API 與被檢查的視窗進行互動。
在目標視窗中執行程式碼
devtools.inspectedWindow.eval() 提供了一種在被檢查視窗中執行程式碼的方式。
這在某種程度上類似於使用 tabs.executeScript() 來注入內容指令碼,但有一個重要的區別:
- 與內容指令碼不同,使用
devtools.inspectedWindow.eval()載入的指令碼不會獲得 “乾淨的 DOM 檢視”:也就是說,它們可以看到頁面指令碼對頁面的更改。
注意:乾淨的 DOM 檢視是一項安全功能,旨在幫助防止惡意頁面透過重新定義原生 DOM 函式的行為來欺騙擴充套件。這意味著您在使用 eval() 時需要非常小心,如果可以的話,應該使用普通的內容指令碼。
使用 devtools.inspectedWindow.eval() 載入的指令碼也看不到內容指令碼定義的任何 JavaScript 變數。
使用內容指令碼
devtools 文件不能直接訪問 tabs.executeScript(),因此如果您需要注入內容指令碼,devtools 文件必須向 background 指令碼傳送一條訊息,要求它注入指令碼。devtools.inspectedWindow.tabId 提供了目標標籤頁的 ID:devtools 文件可以將此 ID 傳遞給 background 指令碼,然後 background 指令碼可以將其傳遞給 tabs.executeScript()。
// devtools-panel.js
const scriptToAttach = "document.body.innerHTML = 'Hi from the devtools';";
window.addEventListener("click", () => {
browser.runtime.sendMessage({
tabId: browser.devtools.inspectedWindow.tabId,
script: scriptToAttach,
});
});
// background.js
function handleMessage(request, sender, sendResponse) {
browser.tabs.executeScript(request.tabId, {
code: request.script,
});
}
browser.runtime.onMessage.addListener(handleMessage);
如果您需要在目標視窗中執行的內容指令碼與 devtools 文件之間交換訊息,建議使用 runtime.connect() 和 runtime.onConnect 來建立 background 頁面和 devtools 文件之間的連線。然後,background 頁面可以維護標籤 ID 與 runtime.Port 物件之間的對映,並使用此對映來路由這兩個作用域之間的訊息。

Devtools APIs 的侷限性
這些 API 基於 Chrome devtools API,但與 Chrome 相比,仍有許多功能缺失。本節列出了截至 Firefox 54 仍未實現的有功能。請注意,devtools API 正在積極開發中,我們預計將在未來的版本中新增對其中大部分功能的支援。
devtools.inspectedWindow
以下功能不受支援:
inspectedWindow.getResources()inspectedWindow.onResourceAddedinspectedWindow.onResourceContentCommitted
inspectedWindow.eval() 的所有選項均不受支援。
使用 inspectedWindow.eval() 注入的指令碼不能使用所有 Console 的命令列輔助函式,但 $0 和 inspect() 都受支援(從 Firefox 55 開始)。
devtools.panels
以下功能不受支援:
panels.elementspanels.sourcespanels.setOpenResourceHandler()panels.openResource()panels.ExtensionPanel.createStatusBarButton()panels.Buttonpanels.ElementsPanelpanels.SourcesPanel
示例
GitHub 上的 webextensions-examples 儲存庫包含幾個使用 devtools 面板的擴充套件示例。
- devtools-panels 使用 devtools 面板。