先上最终效果图,H5 与 App对比:
由于uni-app除H5外 均不支持document、window等浏览器的js API,所以阿里云的验证码https://g.alicdn.com/AWSC/AWSC/awsc.js(dom操作) 无法在App中直接使用。
故改为web-view加载本地html文件做滑动校验操作,通过验证将sessionId token等参数传回vue页面,最终效果与h5一模一样,用户不会感知是web-view加载的验证。
vue 页面代码:
// 点击发送验证码判断是否为App
// #ifdef APP-PLUS
return this.appCreateVerify()
// #endif
// plus创建web-view方法
appCreateVerify() {
// 阿里云验证码 App打开本地verify页面(uni-app本地html存放在根目录/hybrid/html中)
if (wv) {
return wv.show()
}
wv = plus.webview.create('', 'custom-webview', {
'uni-app': 'none',
background: 'transparent',
webviewBGTransparent: true
}, {
appkey: this.nc.appkey,
scene: this.nc.scene
})
wv.loadURL('/hybrid/html/awsc-verify.html')
const currentWebview = this.$scope.$getAppWebview()
// 此处监听uni.postMessage传递参数
plus.globalEvent.addEventListener('plusMessage', msg => {
const result = msg.data.args.data
if(result.name == 'postMessage'){
this.querySendCode(result.arg)
}
})
currentWebview.append(wv)
},
// 发送验证码请求
querySendCode(data) {
if (this.sending) return // 阻止awsc或事件监听 重复触发问题
this.sending = true
LoginSendCode({
phone: this.form.phone,
...data,
scene: this.nc.scene
}).then(res => {
this.sending = false
if (!res.success) {
return uni.showToast({
title: res.msg,
icon: 'none'
})
}
uni.showToast({
title: '验证码发送成功'
})
this.second = 60
const timer = setInterval(() => {
this.second--
if (this.second <= 0) {
clearInterval(timer)
}
}, 1000)
})
},
本地html页面代码:
<style>...设置页面背景透明、滑动验证样式等</style>
<script src="https://g.alicdn.com/AWSC/AWSC/awsc.js"></script>
<script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.1.js"></script>
<script>
document.addEventListener('plusready', function() {
var wv = plus.webview.currentWebview()
// 阿里云滑动验证
window.AWSC.use('nc', function(state, module) {
window.nc = module.init({
appkey: wv.appkey,
scene: wv.scene,
renderTo: 'ncContainer',
success: function(data) {
uni.postMessage({
data
})
wv.hide()
window.nc.reset()
}
})
})
})
</script>
效果还算理想,由此可见其他类似的需要操作dom的功能都能如此实现,小程序同样可以使用 <web-view>标签去实现类似功能
vue页面与本地html文件消息传输方式补充:
最近学到了新的消息传输方式,plus.globalEvent监听uni.postMessage推送的消息会出现重复推送等问题,建议改为Webview url拦截的方式获取html文件数据。
// html中跳转自定义url,会被拦截,不会进行跳转
window.location.href = 'push?params=loading'
// vue页面wv拦截url变更
wv.overrideUrlLoading({mode:'reject'}, e => {
var params = decodeURI(e.url.split('push?params=')[1])
})
url拦截更实时,准确率更高,不会重复接收消息,只有App支持,H5+文档参考:https://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.overrideUrlLoading