H5与原生交互 记录踩坑

目前H5与原生交互的主要方式:

拦截Webview请求的URL Schema

URL Schema是类URL的一种请求格式,可以自定义JSBridge通信的URL Schema,比如:jsbridge://showToast?text=hello ,Native对符合约定的URL进行解析,拿到相关操作、操作,进而调用原生Native的方法,主要有:

  • a标签

  • location.href

  • 使用iframe.src

  • 发送ajax请求
    但是,a标签需要用户操作;location.href可能会引起页面的跳转丢失调用;发送ajax请求Android没有相应的拦截方法;所以使用iframe.src是比较好的方案。

    总结:针对这种拦截Webview请求的URL Schema的交互方式,虽然兼容性还行,但是基于URL的方式,长度受到限制而且不太直观,数据格式有限制,而且建立请求有时间耗时。

JavascriptInterface

//对应安卓端 android为原生自定义
javascript:android.getSomething()   
//对应ios端 h5向原生发送消息msg
window.webkit.messageHandlers.getSomething.postMessage(msg)
//注册供原生调用返回参数的方法
window.getSomething =(result)=>{
  console.log('原生给H5的数据内容',result)
}

jsbridge

//定义与初始化 jsbridge.js
       //注册事件监听,初始化
       function setupWebViewJavascriptBridge(callback) {
            if(isAndroid){
                 if (window.WebViewJavascriptBridge) {
                       callback(WebViewJavascriptBridge)
                 } else {
                     document.addEventListener(
                       'WebViewJavascriptBridgeReady'
                         , function() {
                         callback(WebViewJavascriptBridge)
                     },
                     false
                     );
                 }
           } 
        if(isIos){
          if (window.WebViewJavascriptBridge) { 
            return callback(window.WebViewJavascriptBridge) 
          }
          if (window.WVJBCallbacks) { 
            return window.WVJBCallbacks.push(callback) 
          }
            window.WVJBCallbacks = [callback];
            var WVJBIframe = document.createElement('iframe');
            WVJBIframe.style.display = 'none';
            WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
            document.documentElement.appendChild(WVJBIframe);
            setTimeout(function(){
                 document.documentElement.removeChild(WVJBIframe);
            }, 0);
        }
       }

       //回调函数,接收数据
    if(isAndroid) setupWebViewJavascriptBridge(function(bridge) {
           //默认接收  安卓原生初始化
        bridge.init(function(message, responseCallback) {
               var responseData = 'js默认接收完毕,并回传数据给java';
               responseCallback(responseData); //回传数据给java
           });

           //注册接收参数functionInJs名称 与原生保持一致
         //  bridge.registerHandler("functionInJs", function(data, responseCallback) {
             //  console.log('接收到的数据',data);
             //  var responseData = 'js指定接收完毕,并回传数据';
             //  responseCallback(responseData); //回传数据
        //  });
       })

调用jsbridge

window.setupWebViewJavascriptBridge(bridge => {
// '原生函数名', "传给原生端的数据", callback 回调函数
    bridge.callHandler('getSomething', data, (result) => {
        console.log(result);
    });
})

坑点:Android页面首次调用jsbridge时,返回较慢,后续返回正常,暂未找出原因

  • 补充,第三种方式,使用阿里的离线包容器(mPaaS离线包
    ,需端上配合),调用AlipayJSBridge,使用方式同jsbridge,详情可以查看官方文档 支付宝H5开放文档,目前坑点是ios的导航栏左上按钮返回back事件定义不生效,需端上配合设置

你可能感兴趣的:(H5与原生交互 记录踩坑)