1.情景描述
类似登录验证重置密码等,一般需要验证用户手机号,发送手机验证码之类的情景,这种情况下,可以使用防御机制之一的图文验证码机制,来避免用户在短时间内多次的发送手机验证码
2.开发流程
1)由用户点击发送手机验证码按钮,调用是否需要发送图文验证码的确认接口,例如接口为isSendMsg
2)判断isSendMsg接口返回值(我们主要看情况②):
①如果不需要发送图文验证码,则由后端向短信服务商发送请求,再由服务商向用户发送手机验证码。
②如果需要输入发送图文验证码接口,则需要弹出图文验证码的html标签,并验证验证码是否输入正确。
var html = `
看不清?换一张
`
$.ajax({
url: HOST + '接口路径',
type: 'post',
data: {
phone: phone,
type: type,
},
success: (res) => {
if (!res.rows) {
f()
} else {
var token = res.rows.captcha_token
myModal.popup({
title: '请输入验证码',
content: html,
buttons: [{
label: '确认',
type: "default",
onClick: function () {
var code = myModal.find(".verificationIpt").val();
if(code.length!==4) {
myModal.find('.msgTip').html('请输入四位验证码')
return
}
f(token, code)//验证验证码是否正确的回调函数
}
}, {
label: '取消',
type: "reject"
}]
})
}
},
})
var random = Math.random() * 1;
myModal.find('.verificationBox img').attr('src', HOST + '接口?id=' + token + "&&rand=" + random)
3)当用户输入图文验证码错误时,或者验证码看不清时可以更换图文验证码
myModal.on('click', '.inA', function () {
setToken(phone,token,type)
})
myModal.on('click', '.resetImg', function () {
setToken(phone,token,type)
})
myModal.on('input', '.verificationIpt', function () {
var html = myModal.find('.verificationIpt').val();
if(html.length==0){
myModal.find('.msgTip').html('请输入四位验证码!')
}else if(html.length>4){
myModal.find('.msgTip').html('验证码应为四位')
}else{
myModal.find('.msgTip').html('')
}
})
4)用户验证码输入正确则关闭图文验证码,并发送手机验证码
3.整体代码
//发送验证码按钮
$(".sendverify").click(function(){
let phoneN = $("#phone").val();
let url = "验证码接口";
sendVerify(url,phoneN);
});
//是否发送验证码
imgMsg(phoneN, 1, function (token, code) {
$.ajax({
url: HOST + url,
type: 'post',
data: {
phone: phoneN,
code: code || '',
token: token || '',
},
success: function (res) {
if (res.code == 0) {//发送成功
myModal.popDown()
$(".phone-warn").text('');
$(".sendverify").addClass("sended").attr("disabled", true);
let second = 60;//验证码发送倒计时
$(".sendverify").text(`(` + second + `s)可重新发送`);
let verifyCount = setInterval(function () {
$(".sendverify").text(`(` + (second - 1) + `s)可重新发送`);
--second;
if (second == -1) {
clearInterval(verifyCount);
$(".sendverify").text("发送验证码").removeClass("sended").attr("disabled", false);
second = 60;
};
}, 1000);
} else if (res.code == 500) {
myUI.alert("发送失败,请重新发送!");
}else{
myModal.find('.msgTip').html(res.msg)
setToken(phoneN,token,1)
}
},
error: function (res) {
console.log(res);
}
})
});
function imgMsg(phone, type, f) {
var html = `
看不清?换一张
`
$.ajax({
url: HOST + '接口',
type: 'post',
data: {
phone: phone,
type: type,
},
success: (res) => {
if (!res.rows) {
f()
} else {
var random = Math.random() * 1;
var token = res.rows.captcha_token
myModal.popup({
title: '请输入验证码',
content: html,
buttons: [{
label: '确认',
type: "default",
onClick: function () {
var code = myModal.find(".verificationIpt").val();
if(code.length!==4) {
myModal.find('.msgTip').html('请输入四位验证码')
return
}
f(token, code)
}
}, {
label: '取消',
type: "reject"
}]
})
myModal.find('.verificationBox img').attr('src', HOST + '接口?id=' + token + "&&rand=" + random)
myModal.on('click', '.inA', function () {
setToken(phone,token,type)
})
myModal.on('click', '.resetImg', function () {
setToken(phone,token,type)
})
myModal.on('input', '.verificationIpt', function () {
var html = myModal.find('.verificationIpt').val();
if(html.length==0){
myModal.find('.msgTip').html('请输入四位验证码!')
}else if(html.length>4){
myModal.find('.msgTip').html('验证码应为四位')
}else{
myModal.find('.msgTip').html('')
}
})
}
},
})
}
function setToken(phone,token,type) {
$.ajax({
url: HOST + '接口',
type: 'post',
data: {
phone: phone,
token: token || null,
type: type
},
success: (res) => {
var random = Math.random() * 1;
var token = res.rows.captcha_token
myModal.find('.verificationBox img').attr('src', HOST + '接口?id=' + token + "&&rand=" + random)
},
error: (res) => {
myUI.alert('网络不良,请重试')
}
})
}