WebView与APP交互,即网页通过JSBrige
调用APP的功能,APP也可以通过JSBrige
调用网页提供的方法。最近刚好接触到这一块,记录一下前端侧的实际操作过程,这篇文章适合还没接触过这一块的同学们,这里不讲原理,直接开始实战的过程。
与客户端同学沟通好使用的JSBrige库,我这里使用的是下面这两个库:
https://gitee.com/guome/uni-js-bridge
https://gitee.com/guome/uni-webview-bridge
适用于uni-app框架中webview组件和H5通信的js小工具。此JS是放在H5项目中的;还需要配合uni-app另外封装的webview组件;uni-app的webview组件会放在另一个项目中;
执行以下安装命令
npm i uni-js-bridge --save
or
yarn add uni-js-bridge
以vue项目为例子
在main.js中引入uni-js-bridge
import 'uni-js-bridge'
在publick/index.html中加入以下代码
<script type="text/javascript"> var userAgent = navigator.userAgent; if (userAgent.indexOf('AlipayClient') > -1) { // 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。 document.writeln('<script src="https://appx/web-view.min.js"' + '>' + '<' + '/' + 'script>'); } else if (/QQ/i.test(userAgent) && /miniProgram/i.test(userAgent)) { // QQ 小程序 document.write( '<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"><\/script>', ); } else if (/miniProgram/i.test(userAgent) || /MicroMessenger/i.test(userAgent)) { // 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。 document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"><\/script>'); } else if (/toutiaomicroapp/i.test(userAgent)) { // 字节跳动小程序 JS-SDK 如果不需要兼容字节跳动小程序,则无需引用此 JS 文件。 document.write( '<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"><\/script>'); } else if (/swan/i.test(userAgent)) { // 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。 document.write( '<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"><\/script>', ); } // if (!/toutiaomicroapp/i.test(userAgent)) { // document.querySelector('.post-message-section').style.visibility = 'visible'; // } </script> <!-- uni 的 SDK --> <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
注意:这里使用方法是需要uni-app端那边配合的
首先在uni-app端中需要先注册一个函数提供给H5调用,代码如下:
this.$refs.webViewBridge.registerHandler('nativeShow', (data, callbackFunction) => { // data: h5给客户端的参数 uni.showToast({ title: 'nativeShow' + JSON.stringify(data), icon: 'none' }) // 调用此函数,触发H5回调,里面的参数是给H5用的 // 注意,如果不调用callbackFunction那么H5就无法触发回调函数 callbackFunction({ toH5Data: '这里的参数是提供给H5的回调函数的' // key是可以随便取的 }) })
那么在我们H5端需要按如下方法使用:
UniJsBridge.callHandler( "nativeShow", // 注意这里的名字必须和上面的对应上 { nativeShowData: "nativeShow" }, // 这个参数是传递给uni-app的 res => { // res:就是上面的callbackFunction的参数 // 注意:如果uni-app不调用callbackFunction,那么这个回调函数是不会执行 alert(JSON.stringify(res)); } );
首先在H5中注册一个函数
UniJsBridge.registerHandler("test", (data, responseCallback) => { setTimeout(() => { // data: 是客户端给H5的参数 alert(JSON.stringify(data)); // 把参数传递给客户端,如果不执行的话,uni-app是无法执行回调的 responseCallback('我是给uni-app的参数'); }, 2000); });
然后在uni-app中
this.$refs.webViewBridge.callHandler( 'test', { toH5Data: '33333' }, function(data) { uni.showToast({ title: '哈哈' + data }) } );
[^整个库其实就是这个两个核心API,用这个两个API就可以完成H5和uni-app的通信了;以下提供几个可能也用的上的API]:
首先uni-app端代码
this.$refs.webViewBridge.setDefaultHandler((data, callHandler) => { uni.showToast({ title: 'send' + JSON.stringify(data), icon: 'none' }) callHandler({ send: '给H5的' }) })
h5端代码
UniJsBridge.send({ sendData: "给uni-app的" }, res => { alert(JSON.stringify(res)); });
h5端代码
UniJsBridge.init((data, responseCallback) => { alert(JSON.stringify(data)); responseCallback({ initData: "给uni-app使用的", }); });
uni-app端:可以调用多次,H5端会按队列依次处理
this.$refs.webViewBridge.send({ fff: '1000.0' }, function(data) { uni.showToast({ title: 'send' + JSON.stringify(data), icon: 'none' }) })
具体文档参照:https://uniapp.dcloud.io/api/router
UniJsBridge.uni.navigateTo()
UniJsBridge.uni.redirectTo()
UniJsBridge.uni.reLaunch()
UniJsBridge.uni.switchTab()
UniJsBridge.uni.navigateBack()
UniJsBridge.uni.getEnv()
封装了一下webview组件,再配合uni-js-bridge的npm包可以实现webview和h5双向通信;
代码拉下来跑一下:看一下pages/index/index的例子,封装的组件在web-view-bridge中;
前端页面写在了hybrid/html文件夹
git clone https://gitee.com/guome/uni-webview-bridge.git
文档暂时先参考:https://gitee.com/guome/uni-js-bridge
约定两端通信格式(不管是H5给uni,还是uni给h5都应该是这样的格式)
{ code: 0, // 状态码:0表示成功,其他的失败 data: '返回的数据', // 真正的返回数据 msg: 'success' // 提示信息 }
在uni-app项目中,即使是本地html也不会发生跨域问题;所以不需要封装ajax的转发