????????Chrome 前端(即頁面 JS / Web UI)與客戶端(C++ 后端)的交互機制,是 Chromium 架構中非常核心的一環。下面我將按常見場景,從通道、流程、技術棧幾個角度做一套完整的分析,特別適合你這種在分析和改造瀏覽器底層的開發者。
🔧 典型交互場景分類
場景 | 描述 | 技術路徑 |
---|---|---|
1?? WebUI 頁面與 C++ 后端交互 | 如設置頁、擴展頁等 | WebUI <-> WebUIMessageHandler |
2?? 頁面 JS 與 Extension 后端 | 如插件調用 chrome.runtime.sendMessage | JS <-> Mojo / native extension API |
3?? 頁面 JS 與 Native 功能交互 | 如調用瀏覽器硬件能力 | JS <-> Mojo / C++ Impl |
📍 框架組件總覽圖
1?? WebUI 頁面交互機制詳解
? 構成組件
-
前端:
WebUI HTML + JS
頁面,嵌入在chrome://
或browser://
-
后端:繼承自
content::WebUIController
+WebUIMessageHandler
? 流程詳解
-
前端 JS 發起調用:
chrome.send("MyFunctionName", [arg1, arg2]);
-
后端 C++ 注冊 handler:
void MyHandler::RegisterMessages() override {web_ui()->RegisterMessageCallback("MyFunctionName",base::BindRepeating(&MyHandler::OnMyFunction, base::Unretained(this))); }void MyHandler::OnMyFunction(const base::Value::List& args) {// 處理參數,回調 JSFireWebUIListener("on-data-ready", data); }
-
后端回調前端:
cr.addWebUIListener("on-data-ready", (data) => { ... });
? 應用場景
-
設置頁 (
chrome://settings
) -
下載頁、擴展頁、歷史頁等
2?? Extension 與 Native 通信機制
? 構成組件
-
JS:使用
chrome.runtime.sendMessage
或chrome.extension.getBackgroundPage()
-
后端:繼承
ExtensionFunction
并注冊到ExtensionFunctionRegistry
? 流程示意
chrome.runtime.sendMessage({cmd: "doSomething"}, function(response) {console.log("Response:", response);
});// C++ Extension Function 實現
class DoSomethingFunction : public ExtensionFunction {public:ResponseAction Run() override {// 處理邏輯...return RespondNow(OneArgument(base::Value("OK")));}
};// 注冊宏
EXTENSION_FUNCTION_NAME("extensionInternal.doSomething")
? Chrome 擴展調用的是基于 IPC 和 Mojo 的通道,最終由瀏覽器進程分發請求到對應 ExtensionFunction。
3?? Mojo 通信機制(JS <-> Mojo <-> C++)
適用于較底層的交互,如性能數據、打印、系統 API 等。
? 構成組件
-
前端:JS Binding(
*.mojom-webui.js
) -
后端:C++ Mojo Impl(綁定接口實現)
-
通道:
RenderFrameHost->GetRemoteInterfaces()
or WebUIDataSourceWithMojo
? 示例流程
// JS 側
mojo.bindInterface('my_namespace.MyInterface');
myInterface.doSomething().then((result) => { ... });// mojom 定義
interface MyInterface {DoSomething() => (string result);
}// C++ 實現并綁定
class MyInterfaceImpl : public mojom::MyInterface {public:void DoSomething(DoSomethingCallback callback) override {std::move(callback).Run("Done!");}
};web_ui()->BindInterface(std::make_unique<MyInterfaceImpl>());
🔄 JS 與 C++ 通信方式對比總結
通信方式 | 特點 | 適用場景 |
---|---|---|
chrome.send() | 簡單、基于 WebUI Message | 內部頁面(如 chrome://* ) |
chrome.runtime.sendMessage() | 基于擴展 IPC,功能強大 | 插件調用瀏覽器能力 |
Mojo | 模塊化、高性能、支持多進程 | 深層系統通信(如 Debug、音頻) |