ali验证码接入(预加载)
原生环境预加载页面解决调用时间长的问题
text<template lang="html"> <div> <div id="captcha-element"></div> <div id="button"></div> </div> </template> <script> import { Toast } from 'vant' export default { data() { return {} }, computed: {}, asyncData({ query, error, $axios, n2scheme }) { return { phoneNumber: '', $axios, isWaiting: false, captcha: null, isIOS: query.n2p === 'ios' } }, head: { script: [ { src: 'https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js' } ] }, mounted() { this.init() const self = this // 暴露给原生调用 window.openCaptcha = phoneNumber => { self.openCaptcha(phoneNumber) } }, methods: { actionReport(key, value) { try { if (this.isIOS) { window.webkit && window.webkit.messageHandlers.getVerifyResult.postMessage({ verifyResult: key, msg: value }) } else { window.testInterface && window.testInterface.getVerifyResult(key, value) } } catch (err) { Toast('err', err.message) } }, openCaptcha(phoneNumber) { this.phoneNumber = phoneNumber // 预加载判断验证码是否加载完成,主要限制用户页面加载验证码还未初始化就点击获取验证码,添加loading动画 if (this.captcha) { button.click() } else { this.isWaiting = true } // button && }, init() { const res = Toast.loading({ forbidClick: true, duration: 0 }) const $axios = this.$axios const isWaiting = this.isWaiting const self = this // 弹出式 initAliyunCaptcha({ SceneId: 'xxx', // 场景ID。根据步骤二新建验证场景后,您可以在验证码场景列表,获取该场景的场景ID prefix: 'xxx', // 身份标。开通阿里云验证码2.0后,您可以在控制台概览页面的实例基本信息卡片区域,获取身份标 mode: 'popup', // 验证码模式。popup表示要集成的验证码模式为弹出式。无需修改 element: '#captcha-element', // 页面上预留的渲染验证码的元素,与原代码中预留的页面元素保持一致。 button: '#button', // 触发验证码弹窗的元素。button表示单击登录按钮后,触发captchaVerifyCallback函数。您可以根据实际使用的元素修改element的值 captchaVerifyCallback: captchaVerifyCallback, // 业务请求(带验证码校验)回调函数,无需修改 onBizResultCallback: onBizResultCallback, // 业务请求结果回调函数,无需修改 getInstance: getInstance, // 绑定验证码实例函数,无需修改 slideStyle: { width: 360, height: 40 }, // 滑块验证码样式,支持自定义宽度和高度,单位为px。其中,width最小值为320 px language: 'cn' // 验证码语言类型,支持简体中文(cn)、繁体中文(tw)、英文(en) }) // 绑定验证码实例函数。该函数为固定写法,无需修改 function getInstance(instance) { Toast.clear() self.captcha = instance if (self.isWaiting) { button && button.click() // this.isWaiting = false } const closeBtn = document.getElementById('aliyunCaptcha-btn-close') if (closeBtn) { closeBtn.addEventListener('click', () => { self.actionReport(2, '') }) } const maskBtn = document.getElementById('aliyunCaptcha-mask') if (maskBtn) { maskBtn.addEventListener('click', () => { self.actionReport(2, '') }) } } // 业务请求(带验证码校验)回调函数 /** * @name captchaVerifyCallback * @function * 请求参数:由验证码脚本回调的验证参数,不需要做任何处理,直接传给服务端即可 * @params {string} captchaVerifyParam * 返回参数:字段名固定,captchaResult为必选;如无业务验证场景时,bizResult为可选 * @returns {{captchaResult: boolean, bizResult?: boolean|undefined}} */ async function captchaVerifyCallback(captchaVerifyParam) { const phoneNumber = self.phoneNumber const url = '/mobi/mg/services/x'x'x' const data = new FormData() data.append('verify_param', captchaVerifyParam) data.append('mobile', phoneNumber) const result = await $axios.post(`${url}`, data) const bizResult = result.data.code === 2000 const captchaResult = result.data.code !== 40016 let key = 0 if (captchaResult) { // 验证业务 key = bizResult ? 1 : 0 } else { key = 3 } const verifyResult = { captchaResult, bizResult } self.actionReport(key, result.data.message) return verifyResult // return verifyResult; } // 业务请求验证结果回调函数 function onBizResultCallback(bizResult) {} } } } </script> <style lang="scss" module> :global { .container { padding-bottom: 0; } } .container { position: relative; max-width: 800px; margin: 0 auto; height: 100%; background: #fff; background-size: 28%; } .intro { text-align: center; margin-top: 20px; padding: 0; } .logo { max-width: 80px; } .title { font-weight: 500; color: #444; font-size: 32px; } .desc { color: #333; line-height: 1.5; font-size: 14px; } .download { margin-top: 20px; } .download a { display: inline-block; width: 118px; margin: 16px 16px 0 0; padding: 8px 0; border-radius: 20px; line-height: 20px; font-size: 12px; text-decoration: none; border: 1px solid #dcdfe6; color: #606266; } .sooner { margin-top: 8px; font-size: 12px; color: #f56c6c; text-decoration: underline; } .sooner a { color: inherit; } .download .download-btn { display: inline-block; width: auto; margin: 0; padding: 10px; border-radius: 5px; line-height: 20px; text-decoration: none; border: none; font-size: 16px; color: #fff; background-color: #66b1ff; } .download-qrcode { width: 100px; } .tip { color: #333; font-size: 12px; } .slogan { font-weight: 400; font-size: 20px; } .phone { position: absolute; left: 50%; bottom: 0; width: 90%; transform: translateX(-50%); pointer-events: none; } .background { max-width: 100%; } .top { position: relative; height: 100vh; &::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 20px; background-image: linear-gradient( 0deg, hsla(0, 0%, 59%, 0.15), hsla(0, 0%, 59%, 0) ); z-index: 3; } } .section { border-bottom: 1px solid #f0f0f0; padding: 60px 0 30px; text-align: center; &-title { font-weight: 400; font-size: 20px; } &-desc { padding: 10px 30px 25px; line-height: 1.5; font-size: 15px; font-weight: 300; } &-img { max-width: 200px; margin-top: 20px; } } .bottom { text-align: center; padding: 40px 0; } .back-home { display: block; margin-top: 15px; font-size: 15px; color: #999; -webkit-tap-highlight-color: rgba(#000, 0); } .size { color: #888; font-size: 13px; margin-top: 8px; } </style>