An Introduction to JSBridge: Origin, Dual‑Communication Principles, and Usage
This article explains the origin of JSBridge, compares H5 and native development, details the two‑way communication mechanisms—including URL Scheme interception, prompt rewriting, and API injection—and provides practical usage guidelines and code examples for integrating JSBridge in hybrid mobile apps.
JSBridge is a JavaScript‑based bridge that connects Web (H5) pages with native code in mobile applications, enabling two‑way communication so that JavaScript can call native functions (e.g., opening the camera, accessing the album, fingerprint payment) and native code can invoke JavaScript.
Origin of JSBridge
With the rapid proliferation of mobile devices, developers often need to combine native and H5 approaches in hybrid applications. Early solutions like Cordova provided APIs for JavaScript to call native code, but JSBridge became widely adopted in China as mobile internet grew.
H5 vs. Native Comparison
Aspect
H5
Native
Stability
Relies on system browser kernel, less stable
Uses native kernel, more stable
Flexibility
Fast iteration, easy release
Slower iteration, app‑store review required
Network Impact
Higher
Lower
Smoothness
Sometimes slow, feels laggy
Fast loading, smoother experience
User Experience
Limited by browser capabilities
Rich native APIs, better UX
Portability
Cross‑platform (PC, iOS, Android)
Separate codebases for iOS and Android
Dual‑Communication Principles
JS Calls Native
Common methods include intercepting URL Scheme , rewriting prompt , and injecting APIs.
Intercepting URL Scheme
Both Android and iOS can capture a custom URL scheme and decide whether to execute native logic.
On Android, WebView provides shouldOverrideUrlLoading to intercept the request:
public class CustomWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Scene 1: intercept request, handle scheme
if (url.equals("xxx")) {
// handle
view.loadUrl("javascript:setAllContent(" + json + ");");
return true;
}
return super.shouldOverrideUrlLoading(url);
}
}On iOS, WKWebView can process the intercepted scheme:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([navigationAction.request.URL.absoluteString hasPrefix:@"xxx"]) {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
}
decisionHandler(WKNavigationActionPolicyAllow);
}This method is flexible and avoids security issues, but URL length must be controlled.
Rewriting Prompt and Other Native JS Methods
Before Android 4.2, addJavascriptInterface was used, but due to security concerns developers now intercept alert , confirm , prompt , and console.log via WebView callbacks.
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, final JsPromptResult result) {
String handledRet = parentEngine.bridge.promptOnJsPrompt(origin, message, defaultValue);
// ...
return true;
}On iOS, the three WKUIDelegate methods must be implemented to handle these dialogs.
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:nil];
}Injecting API
By injecting an object into the WebView’s JavaScript context, JS can directly call native methods.
gpcWebView.addJavascriptInterface(new JavaScriptInterface(), "nativeApiBridge");
public class JavaScriptInterface {
Context mContext;
JavaScriptInterface(Context c) { mContext = c; }
public void share(String webMessage) { /* Native logic */ }
}JS usage:
window.NativeApi.share(xxx);iOS provides window.webkit.messageHandlers for similar injection.
window.webkit.messageHandlers.share.postMessage(xxx);Native Calls JS
Native can execute JavaScript by loading a URL or using evaluation APIs.
Android (pre‑4.4) uses loadUrl("javascript:" + js) ; Android 4.4+ prefers evaluateJavascript which returns a result without refreshing the WebView.
webView.loadUrl("javascript:" + javaScriptString);
webView.evaluateJavascript(javaScriptString, new ValueCallback
() {
@Override
public void onReceiveValue(String value) {
// handle result
}
});iOS WKWebView uses evaluateJavaScript:completionHandler: :
func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil) {
// ...
}Using JSBridge
Two main ways to reference the bridge:
H5‑side local import (npm package) – simple but tightly coupled to a specific implementation.
Native‑side injection – preferred in our team; keeps API consistent with native code but requires runtime checks for bridge availability.
Typical H5‑to‑Native call pattern:
params = {
api_version: "xxx",
title: "xxx",
filename: "xxx",
image: "xxx",
url: "xxx",
success: function(res) { /* success */ },
fail: function(err) {
if (err.code == '-2') {
// API version not supported
} else {
const msg = err.msg;
Toast.fail(msg);
}
}
};
window.NativeApi.share(params);A helper function checks whether the app environment and bridge exist before invoking native methods:
reqNativeBridge(vm, fn) {
if (!isApp()) {
vm.$dialog.alert({ message: "此功能需要访问 APP 才能使用" });
} else if (!window.NativeApi) {
vm.$dialog.alert({ message: "请更新到最新 APP 使用该功能" });
} else {
fn && fn(err => {
vm.$dialog.alert({ message: "请更新到最新 APP 使用该功能" });
});
}
}Conclusion
The article provides a concise overview of JSBridge’s principles, common implementation techniques, and practical usage patterns, offering a useful reference for developers new to hybrid mobile development.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.