作为一个穷公司的前端,什么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()
})