WebViewJavascriptBridge H5交互

作为一个穷公司的前端,什么app的都是奢侈,但是呢,保不齐要对接一些有逼格的公司业务,所以呢,也算是在所谓hibrid模式下,找到了一丝生存的希望

大致情况是这样,需要在对接方的app中嵌入一些我方的h5页面。这套业务流程大体总结如下

首先约定好,app首次跳转过来是的方式,比如url外加一个token,然后h5页面拿到这个token再去通过接口校验身份的合法性。这中间呢,还可以加上相互协商好的加解密方式、以及token验证一次就失效等,进一步确保安全性。打通两者的用户态等

接着就是之后的相互调用了,借助WebViewJavascriptBridge,app端不是很懂,理解大概是一个库,可以注册到window对象上,从而达到相互调用的效果。h5这边涉及到的大体如下

<script language="javascript">
      var u = navigator.userAgent;
      var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
      var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
      // alert('是否是Android:'+isAndroid);
      // alert('是否是iOS:'+isiOS);
      function setupWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
          callback(WebViewJavascriptBridge)
        } else {
          document.addEventListener(
            'WebViewJavascriptBridgeReady'
            , function() {
              callback(WebViewJavascriptBridge)
            },
            false
          );
        }
        if (window.WebViewJavascriptBridge) { return callback(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)
      }
      setupWebViewJavascriptBridge(function(bridge) {
        if(isAndroid){
         bridge.init(function(message, responseCallback) {
            responseCallback("");
          });
        }
      })
    </script>

在全局文件如index.html中添加setupWebViewJavascriptBridge函数,相当在window对象上注册了WebViewJavascriptBridge,h5调用native

// 调用 native
window.WebViewJavascriptBridge && window.WebViewJavascriptBridge.callHandler('nativeHandler', data, res => {})

native调用H5,当然先要在全局注册好相关函数,这边采用在enrich时直接给出某个文件nativePlugin,定义到某变量上直接给到vue原生属性中,具体可参考

import { decrypt } from '../enrich/crypto'
import _ from 'lodash'
import store from '../store'

const $nativeBridge = {
  passwordIsRight: (cb) => {
    // 输入交易密码后回调js  {“token”:”用户token信息”,”userCode”:”用户id”,”orderNo”:”订单编码”}
    window.WebViewJavascriptBridge && window.WebViewJavascriptBridge.registerHandler('passwordIsRight', (data, responseCallback) => {
      data = typeof data === 'string' ? JSON.parse(data) : data
      let pwData = _.pick(data, ['token', 'userCode'])
      try {
        _.forEach(_.omit(data, ['token', 'userCode']), (val, key) => {
          pwData[key] = decrypt(val)
        })
      } catch (err) {
        console.log('decrypt bankData err', err)
      }

      _.isFunction(cb) && cb(process.env.NODE_ENV === 'development' ? data : pwData)
    })
  },
  // 用户授权后告知js {“token”:”用户token信息”,”userCode”:”用户id”,”status”:”开户状态”}
  alreadyAuthorizate: (cb) => {
    window.WebViewJavascriptBridge && window.WebViewJavascriptBridge.registerHandler('alreadyAuthorizate', (data, responseCallback) => {
      let userData = typeof data === 'string' ? JSON.parse(data) : data
      store.dispatch('setLoginData', userData)
      _.isFunction(cb) && cb(userData)
    })
  }
}

export default {
  install (Vue, options) {
    if (this.installed) return

    this.installed = true

    Object.defineProperties(Vue.prototype, {
      $nativeBridge: {
        get () {
          return $nativeBridge
        }
      }
    })
  }
}

外面直接vue.use(nativePlugin),调用后触发

this.$nativeBridge.alreadyAuthorizate((userData) => { // 从native传过来的的数据
      console.log('alreadyAuthorizate userData', userData)
      this.nextRoute()
    })

猜你喜欢

转载自blog.csdn.net/banxia561/article/details/81098198