台州市城市建设规划局网站,自己怎么做一个网页,上海 网站建设,泰安网站优化推广作者#xff1a;senntyousegmentfault.com/a/1190000016759517现在移动端 web 应用#xff0c;很多时候都需要与原生 app 进行交互、沟通#xff08;运行在 webview中#xff09;#xff0c;比如微信的 jssdk#xff0c;通过 window.wx 对象调用一些原生 app 的功能。所以… 作者senntyousegmentfault.com/a/1190000016759517现在移动端 web 应用很多时候都需要与原生 app 进行交互、沟通运行在 webview中比如微信的 jssdk通过 window.wx 对象调用一些原生 app 的功能。所以这次就来捋一捋 h5 与原生 app 交互的原理。h5 与原生 app 的交互本质上说就是两种调用app 调用 h5 的代码h5 调用 app 的代码1. app 调用 h5 的代码因为 app 是宿主可以直接访问 h5所以这种调用比较简单就是在 h5 中曝露一些全局对象包括方法然后在原生 app 中调用这些对象。javascriptwindow.sdk { double value value * 2, triple value value * 3,};androidwebview.evaluateJavascript(window.sdk.double(10), new ValueCallbackString() { Override public void onReceiveValue(String s) { // 20 }});iosNSString *func window.sdk.double(10);NSString *str [webview stringByEvaluatingJavaScriptFromString:func]; // 202. h5 调用 app 的代码因为 h5 不能直接访问宿主 app所以这种调用就相对复杂一点。这种调用常用有两种方式由 app 向 h5 注入一个全局 js 对象然后在 h5 直接访问这个对象由 h5 发起一个自定义协议请求app 拦截这个请求后再由 app 调用 h5 中的回调函数2.1 由 app 向 h5 注入一个全局 js 对象这种方式沟通机制简单比较好理解并且对于 h5 来说没有新的东西所以是比较推荐的一种方式。但这种方式可能存在安全隐患详细查看 你不知道的 Android WebView 使用漏洞。androidwebview.addJavascriptInterface(new Object() { JavascriptInterface public int double(value) { return value * 2; } JavascriptInterface public int triple(value) { return value * 3; }}, appSdk);iosinterface AppSdk : NSObject{}- (int) double:(int)value;- (int) triple:(int)value;endimplementation AppSdk- (int) double:(int)value { return value * 2;}- (int) triple:(int)value { return value * 3;}endJSContext *context[webview valueForKeyPath:documentView.webView.mainFrame.javaScriptContext];AppSdk *appSdk [AppSdk new];context[appSdk] appSdk;javascriptwindow.appSdk.double(10); // 202.2 由 h5 发起一个自定义协议请求这种方式要稍复杂一点因为需要自定义协议这对很多前端开发者来说是比较新的东西。所以一般不推荐这种方式可以作为第一种方式的补充。大致需要以下几个步骤由 app 自定义协议比如 sdk://action?params在 h5 定义好回调函数比如 window.bridge{getDouble:value{},getTriple:value{}}由 h5 发起一个自定义协议请求比如 location.hrefsdk://double?value10app 拦截这个请求后进行相应的操作获取返回值由 app 调用 h5 中的回调函数比如 window.bridge.getDouble(20);javascriptwindow.bridge { getDouble: value { // 20 }, getTriple: value { // more }};location.href sdk://double?value10;androidwebview.setWebViewClient(new WebViewClient() { Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // 判断如果 url 是 sdk:// 打头的就拦截掉 // 然后从 url sdk://action?params 中取出 action 与params Uri uri Uri.parse(url); if ( uri.getScheme().equals(sdk)) { // 比如 action double, params value10 webview.evaluateJavascript(window.bridge.getDouble(20)); return true; } return super.shouldOverrideUrlLoading(view, url); }});ios- (BOOL)webview:(UIWebView *)webview shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { // 判断如果 url 是 sdk:// 打头的就拦截掉 // 然后从 url sdk://action?params 中取出 action 与params NSString *urlStr request.URL.absoluteString; if ([urlStr hasPrefix:sdk://]) { // 比如 action double, params value10 NSString *func window.bridge.getDouble(20); [webview stringByEvaluatingJavaScriptFromString:func]; return NO; } return YES;}