CEF 基於多進程架構:Browser 進程管理 UI、網絡等;Render 進程負責頁面渲染和 JS 執行。JS 與 C++ 交互發生在 Render 進程。
CefFrame::ExecuteJavaScript()。OnContextCreated 中獲取 window,用 CefV8Value::CreateFunction 創建函數並綁定,JS 調用時觸發 CefV8Handler::Execute。OnWebKitInitialized 中調用 CefRegisterExtension 定義 JS 對象及其 native 方法,JS 直接調用。class ClientAppRenderer : public CefApp, public CefRenderProcessHandler {
CefRefPtr m_v8Handler;
public:
ClientAppRenderer() : m_v8Handler(new ClientV8Handler) {}
CefRefPtr GetRenderProcessHandler() override { return this; }
void OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context) override {
CefRefPtr window = context->GetGlobal();
CefRefPtr func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);
window->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);
}
void OnWebKitInitialized() override {
string js_code = "var app; if(!app) app={}; (function(){ app.GetId=function(){ native function GetId(); return GetId(); }; })();";
CefRegisterExtension("v8/app", js_code, m_v8Handler);
}
};
class ClientV8Handler : public CefV8Handler {
public:
bool Execute(const CefString& name, CefRefPtr object,
const CefV8ValueList& args, CefRefPtr& retval, CefString& exception) override {
if (name == "NativeLogin") {
if (args.size() == 2) {
CefString user = args[0]->GetStringValue();
CefString pwd = args[1]->GetStringValue();
// 此處可做原生驗證邏輯
retval = CefV8Value::CreateInt(0);
} else retval = CefV8Value::CreateInt(2);
return true;
} else if (name == "GetId") {
// 演示 C++ 執行 JS
CefRefPtr frame = CefV8Context::GetCurrentContext()->GetBrowser()->GetMainFrame();
frame->ExecuteJavaScript("alert('Hello from native')", frame->GetURL(), 0);
retval = CefV8Value::CreateString("72395678");
return true;
}
return false;
}
};
<script>
function Login() {
window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value);
}
function GetId() {
alert("get id from native by extensions: " + app.GetId());
}
</script>
<form>
UserName: <input id="userName" type="text" /> Password: <input id="password" type="text" />
<input onclick="Login()" type="button" value="Login" />
</form>
<hr/>
<input onclick="GetId()" type="button" value="GetId" />