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) { // 处理参数,回调 JS FireWebUIListener("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、音频) |