跪拜 Guibai
← All articles
JavaScript

WKWebView's `window` Is Just a Global Object — Here's How H5-to-Native Messaging Actually Works

By 大龄秃头程序员 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Misunderstanding `window` leads to brittle bridge code and security gaps. Once an iOS developer sees that `window` is just the JS global and the bridge lives in a subtree underneath it, the entire WKWebView communication model becomes a straightforward message dispatch system rather than a black box.

Summary

Many iOS developers treat `window` as synonymous with JSBridge, but it's simply the web page's global runtime object. WebKit injects `window.webkit.messageHandlers` when Native registers a script message handler, and that subtree becomes the actual bridge entry point. H5 calls Native by posting a message through a named handler channel; Native calls back by evaluating a JavaScript string that invokes a function attached to `window`.

The communication is message-passing, not direct function invocation. H5 sends a structured message with an action identifier, and Native dispatches it inside `WKScriptMessageHandler`. The return path uses `evaluateJavaScript` to execute a pre-defined H5 function, completing the round trip. This pattern scales into full JSBridge protocols with module routing, callback IDs, and error codes — but the foundation stays the same two primitives.

Common misconceptions include thinking `window` is an iOS-injected object, that H5 directly calls Swift methods, or that Native callbacks are limited to plain strings. In practice, Native assembles arbitrary JavaScript and must handle escaping, injection risks, and serialization costs.

Takeaways
`window` is the JavaScript runtime's global object, not a bridge or an iOS-injected construct.
Native registers a handler name via `WKUserContentController.add()`; WebKit exposes it at `window.webkit.messageHandlers.<name>`.
H5 calls Native by posting a message object through that handler, not by directly invoking a Swift method.
Native receives the message in `WKScriptMessageHandler` and dispatches based on an action field or similar identifier.
Native calls back to H5 by executing a JavaScript string via `webView.evaluateJavaScript()`, typically invoking a function on `window`.
Production JSBridge protocols extend this with module/method routing, callback IDs, error codes, and Promise wrappers.
Escaping, injection safety, and large-payload serialization cost are real engineering concerns when assembling `evaluateJavaScript` strings.
Conclusions

Framing `window` as the container rather than the bridge itself resolves a persistent category error among mobile developers working with hybrid stacks.

The postMessage/evaluateJavaScript pair is functionally an RPC layer, but many teams reinvent routing and serialization on top of it without recognizing the pattern.

Calling `evaluateJavaScript` with hand-assembled strings is a vector for injection and escaping bugs that mature JSBridge libraries abstract away, yet the underlying primitive remains unchanged.

Concepts & terms
WKUserContentController
The iOS class that manages the interaction between native code and JavaScript in a WKWebView. It is used to add script message handlers that expose named channels to the web page.
WKScriptMessageHandler
A protocol method that receives messages sent from JavaScript via `window.webkit.messageHandlers.<name>.postMessage()`. The `name` property matches the handler name registered in Native.
evaluateJavaScript
A WKWebView method that executes a raw JavaScript string in the context of the current web page. It is the primary mechanism for Native-to-H5 communication on iOS.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗