常见问题

更新时间:

本文汇总了使用验证码时的常见问题。

产品QA

Q1: 验证码的生命周期是怎样的?

生命周期流程图如下:

image

整个流程中只需初始化一次验证码,无需再多次调用initAliyunCaptcha方法。阿里云验证码2.0不支持单个页面注册多个验证码实例,多次调用初始化方法会重复添加元素和注册事件,造成验证表现异常。

如果出现一次验证流程发出了多个验证请求,可以考虑为重复初始化的问题,需要排查触发调用初始化方法的按钮是否做了防抖处理。

Q2:一个页面有多处用到验证码怎么处理?

  • 方法1:使用弹出式模式(popup),将传入initAliyunCaptcha方法的button元素设置为一个隐藏元素,然后在需要触发验证码的元素上绑定相关事件(一般为点击事件),在事件回调函数中用JavaScript触发上述button元素的点击事件,即可触发验证码弹窗,整个页面共享一个验证码实例。

  • 方法2:将验证码封装为一个组件,在需要调用的地方使用,初始化相关参数可作为props传入,验证流程完毕后需要将验证码组件卸载(从dom中移除)。更多详情,请参见客户端接入Demo示例下载

Q3:手机验证码发送场景怎么接入验证码?

详情请参见下载发送手机短信场景Demo示例(React)

Q4:如何手动刷新/销毁验证码,或者手动弹出/关闭验证码弹窗?

调用验证码实例对应方法。其中,无痕模式首次验证不支持下列方法。

方法名

说明

示例

show

显示验证码元素/蒙板

captcha.show()

hide

隐藏验证码元素/蒙板

captcha.hide()

refresh

刷新验证码(无痕形态不支持)

captcha.refresh()

destroyCaptcha

销毁验证码(实例及元素)

captcha.destroyCaptcha()

Q5:APP端接入,如何在APP侧进行验证请求?

可以在captchaVerifyCallback中调用自定义Java接口testJsInterface(安卓)或通过WkScriptMessageHandler协议实现JavaScriptWKWebView交互的方法(iOS),将captchaVerifyParam透给APP侧,然后关闭验证码H5窗口并发起验证请求,获取到验证结果后APP侧自行提示验证是否通过,如不通过则再次弹出H5窗口重新验证即可。该场景下不建议使用无痕验证模式,因为每次验证均会重新初始化验证码(新的验证码周期),导致每次均为无痕验证,即使无痕不通过下次验证也不会进入二次验证形态,因此防护效果稍弱。

Q6:在触发验证码弹窗之前需要做自定义业务操作怎么处理?

可以将传入initAliyunCaptchabutton元素设置为一个隐藏元素,然后在需要触发验证码的元素上绑定相关事件(一般为点击事件), 在事件回调中做业务操作(如业务参数校验),通过之后再用JavaScript触发上述button元素的点击事件。

Q7:无痕模式的验证逻辑是怎样的?

无痕验证流程图如下:

image
  • captchaResult为false,将会自动弹出二次验证。

  • captchaResult为true,执行onBizResultCallback,做业务提示、跳转等逻辑。

Q8:Uncaught TypeError: Cannot set properties of undefined (setting 'onclick') 报错如何解决?

没找到element或者button元素,这两个元素需要在DOM中存在,初始化参数需要传入正确的元素id。

Q9:设置了slideStyle参数,怎么拼图下的滑块没有生效?

slideStyle参数只对滑块验证码生效,拼图验证码不受该参数影响。拼图验证码的答案为固定的,前端不可以修改图片/滑块的长度和宽度,否则会造成验证异常。

Q10:captchaVerifyCallback里返回了验证结果信息,但是为什么验证码没有反应呢?

可能的原因如下:

  1. return语句是在如ajax的success回调函数中声明的,而外面的captchaVerifyCallback是没有return出去的,因此验证码SDK获取不到验证结果,造成验证流程阻塞。因此,需要将返回体封装成一个promise,然后在回调中将结果resolve出去即可。

    正确示例

    async function captchaVerifyCallback(captchaVerifyParam) {
      return new Promise((resolve) => {
        $.ajax({
          Url: 'xxxx',
          data: 'xxxx',
          success: (result) => {
            resolve({
              captchaResult: true,
              bizResult: false,
            });
          },
        });
      });
    }

    错误示例

    async function captchaVerifyCallback(captchaVerifyParam) {
      $.ajax({
        Url: 'xxxx',
        data: 'xxxx',
        success: (result) => {
          return {
            captchaResult: true,
            bizResult: false,
          };
        },
      });
    }
  2. 嵌入式下,如果需要滑动完成/图片点选完成后立即发送请求,则需要在初始化方法中添加immediate: true参数。

Q11:参考demo代码接入了,为什么验证码没有渲染出来?

可能的原因如下:

  • 初始化请求失败,初始化请求即https://prefix.captcha-open.aliyuncs.com这个接口的请求,可能是因为网络原因导致的请求失败或者超时;或者返回值中有Forbidden.AccountAccessDenied时,可能为阿里云账号异常或欠费导致的请求失败。此时浏览器开发者工具的console中会有相应的网络报错信息。

  • 若浏览器开发者工具的console中没有报错信息,且初始化请求成功了,则有可能是请求返回值中CaptchaType字段是为TRACELESS,此时是无痕验证模式,首次初始化不会渲染图形验证,具体验证逻辑可以参考Q7:无痕模式的验证逻辑是怎样的?

Q12:微信小程序接入上传代码提示代码包过大,如何解决?

出于安全考虑,插件代码使用了较为复杂的混淆机制,代码体积较大。目前可使用微信小程序的分包机制来解决,即将使用到验证码的页面分包。可参考微信原生使用分包Taro微信小程序独立分包uni-app中分包内引入插件代码包