Vue之集成阿里云滑块验证

2,809 阅读1分钟

采用阿里云的滑块验证,首先注册并申请appKey。

  1. public > index.html中引入js
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">
    <!-- 国内使用 -->
    <script type="text/javascript" charset="utf-8" src="//g.alicdn.com/sd/nch5/index.js?t=2015052012"></script>
    <!-- 若您的主要用户来源于海外,请替换使用下面的js资源 -->
    <!-- <script type="text/javascript" charset="utf-8" src="//aeis.alicdn.com/sd/nch5/index.js?t=2015052012"></script> -->
</head>
  1. 新建文件no-captcha.vue
<template>
  <div id="__nc" style="width:100%;margin-bottom:20px;">
    <div id="nc"></div>
  </div>
</template>
<script>
export default {
  name: "machineCheck",
  data() {
    return {
      platform: '',
      isWeChat: false,
    }
  },
  mounted() {
    // this.platformFunC() //h5移动端机型系统判断
    this.check()
  },
  props: {
    logVal: Number
  },
  methods: {
    // 机型系统判断
    platformFunC() {
      const u = navigator.userAgent;
      const ua = navigator.userAgent.toLowerCase();
      let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
      let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
      let weChat = ua.match(/MicroMessenger/i) == "micromessenger";
      if (isiOS) {
        this.platform = 'ios';
      } else if (isAndroid) {
        this.platform = 'android';
      }
      this.isWeChat = weChat;
    },
    check(){
      let _that = this
      // 实例化nc
      const nc_token = ["你申请的appKey", (new Date()).getTime(), Math.random()].join(':');
      const nc = NoCaptcha.init({
        renderTo: '#nc',
        appkey: '你申请的appKey',
        scene: 'nc_message_h5',
        token: nc_token,
        trans: {"key1": "code200"},
        elementID: ["usernameID"],
        is_Opt: 0,
        language: "cn",
        timeout: 10000,
        retryTimes: 5,
        errorTimes: 5,
        inline: false,
        apimap: {
          // 'analyze': '//a.com/nocaptcha/analyze.jsonp',
          // 'uab_Url': '//aeu.alicdn.com/js/uac/909.js',
        },
        bannerHidden: false,
        initHidden: false,
        callback: function (data) {
          data.nc_token = nc_token
          data.scene = 'nc_message_h5'
          let dataArr = data
          _that.$emit('ncData', dataArr)
          if (_that.logVal === 1) {
            _that.childMethod()
          }
          if (_that.platform === 'ios') {
            window.webkit.messageHandlers.getNcData.postMessage(JSON.stringify(dataArr));
          } else if (_that.platform === 'android') {
            window.js.getNcData(JSON.stringify(dataArr));
          }

          // console.log(data)
          // window.console && console.log('nc_token:' + nc_token)
          // window.console && console.log('csessionid:' + data.csessionid)
          // window.console && console.log('sig:' + data.sig)
        },
        error: function (s) {
        }
      });
      NoCaptcha.setEnabled(true);
      nc.reset();//请务必确保这里调用一次reset()方法

      NoCaptcha.upLang('cn', {
        'LOADING':"加载中...",//加载
        'SLIDER_LABEL': "请向右滑动验证",//等待滑动
        'CHECK_Y':"验证通过",//通过
        'ERROR_TITLE':"非常抱歉,这出错了...",//拦截
        'CHECK_N':"验证未通过", //准备唤醒二次验证
        'OVERLAY_INFORM':"经检测你当前操作环境存在风险,请输入验证码",//二次验证
        'TIPS_TITLE':"验证码错误,请重新输入"//验证码输错时的提示
      });
    },
    childMethod() {
      // console.log(this.$parent.$parent)
      this.$parent.$parent.reSendCode();
    }
  }
}
</script>

<style scoped></style>
  1. 在需要滑块验证的页面中引入上面的组件
<template>
  <div>
    <section class="four_container">
      <div class="form_section">
        <el-form>
          <el-form-item label="姓名" style="padding-left: 14px">
            <el-input
              v-model="search_form.userName"
              placeholder="请填写您的证件姓名"
            ></el-input>
          </el-form-item>
          <el-form-item label="证件号">
            <el-input
              v-model="search_form.cardNo"
              placeholder="请填写您的证件号码"
            ></el-input>
          </el-form-item>
          <el-form-item label="手机号">
            <div class="getCodeBox">
              <el-input
                v-model="search_form.userPhone"
                placeholder="请填写您的手机号"
                maxlength="11"
              ></el-input>
              <p
                :class="isSendCode ? 'sendCode' : 'sendCode_no'"
                @click="isSendCode ? sendCode() : ''"
              >
                {{ codeText }}
              </p>
            </div>
          </el-form-item>
          <machineCheck
            v-on:ncData="ncData"
            :logVal="1"
            v-if="ncShow"
          ></machineCheck>

          <el-form-item label="验证码">
            <el-input
              v-model="search_form.captcha"
              placeholder="请输入手机验证码"
              maxlength="6"
            ></el-input>
          </el-form-item>
        </el-form>
        <p
          :class="isSearchData ? 'search_button_op' : 'search_button'"
          @click="isSearchData ? submit_search() : ''"
        >
          查询
        </p>
      </div>
    </section>
  </div>
</template>

<script>
import axiosApi from "../../../network/dataRequest/DataRequest.js";
import machineCheck from "../../../components/comMon/no-captcha.vue";
import axios from "axios";

export default {
  name: "",
  data() {
    return {
      isSendCode: false, //发送验证码 按钮是否能点击
      isSearchData: false, //查询 按钮是否能点击
      codeText: "获取验证码", //短信验证码
      codeStatus: 0, //发送验证码的状态
      totalTime: 60, //倒计时总时间
      interverTime: null, //定时器
      ncShow: false, //人机校验显示隐藏
      nc_DataArr: {},
      code_form: {
        captchaType: "scoreOffline",
        nc_token: "",
        phoneNumber: "",
        scene: "",
        sessionId: "",
        sig: "",
      },
      search_form: {
        captcha: "",
        cardNo: "",
        userName: "",
        userPhone: "",
      },
    };
  },
  watch: {},
  props: {},
  components: { machineCheck },
  mounted() {},
  methods: {
    ncData(ncData) {
      this.nc_DataArr = ncData;
    },
    // 点击发送验证码
    sendCode() {
      // 防止用户重复点击
      if (!this.interverTime) {
        if (this.search_form.userPhone) {
          // 判断用户手机号是否正确
          if (!/^1[3456789]\d{9}$/.test(this.search_form.userPhone.trim())) {
            this.ncShow = false;
            this.$message({
              showClose: true,
              message: "手机号格式错误",
              type: "error",
            });
            return false;
          } else {
            this.nc_DataArr = {};
            if (this.nc_DataArr.code !== 0) {
              this.ncShow = true;
              return false;
            }
            this.reSendCode();
          }
        } else {
          this.ncShow = false;
          this.$message({
            showClose: true,
            message: "手机号不能为空",
            type: "error",
          });
        }
      }
    },
    //发送验证码重复部分
    reSendCode() {
      this.startTime();

      this.code_form = {
        captchaType: "scoreOffline",
        nc_token: this.nc_DataArr.nc_token,
        phoneNumber: this.search_form.userPhone,
        scene: "nc_message_h5",
        sessionId: this.nc_DataArr.csessionid,
        sig: this.nc_DataArr.sig,
      };
      let that = this;
      axiosApi.captchaUserMachineSendApi(this.code_form).then((res) => {
        console.log(res);
        if (res.data.code == 0) {
          that.ncShow = false;
        } else {
          this.$message({
            showClose: true,
            message: res.data.msg,
            type: "error",
          });
        }
        that.ncShow = false;
      });
    },
    //开启定时器
    startTime() {
      this.codeStatus = 1;
      this.isSendCode = false;
      this.interverTime = setInterval(() => {
        this.totalTime--;
        this.codeText = this.totalTime + "秒后重新获取";
        if (this.totalTime <= 0) {
          this.clearTime();
        }
      }, 1000);
    },
    // 清除计时器并初始化数据
    clearTime() {
      clearInterval(this.interverTime);
      this.totalTime = 60;
      this.codeText = "获取验证码";
      this.codeStatus = 0;
      this.interverTime = null;
      this.isSendCode = true;
    },
  },
};
</script>

<style scoped lang="scss" rel="stylesheet/scss"></style>