此做法为应对以下场景:
用户点击了“获取验证码”后开始做倒计时60s,如果用户通过F5刷新一下页面,存在内存里面的倒计时对象就会被重置,用户又能继续获取验证码,可能会被某些不坏好意的人通过此方法恶意刷验证码。
为防止用户恶意刷验证码,虽然一般情况下后端都会做了限制,但是如果可以先在前端层面限制住,减少请求,节约带宽不更好?
此处的实现方法是利用cookie在浏览器的时效属性来实现,例子中使用了Jq + jq.cookie,例子里面我都引用了cdn地址。
PS: cookie是需要在服务器环境下才能操作的,如果只是为了在本地验证的,这里推荐一个本地跑项目的工具————live-server,个人特别方便,已经在用webpack-server、fis-server......之类的就不用啦,直接复制代码到你的项目中跑即可
cookie_downTime.js:
var vm = new Vue({
el: "#vm",
data: function () {
return {
spacing: 60, //再次获取验证码的初始间隔秒数
remainder: 0, //距离再次获取验证码的剩余秒数
timer: null,//定时器
}
},
mounted: function () {
var _this = this;
//检查上一个倒计时是否还有剩余秒数
if ($.cookie("test_captcha")) {
_this.remainder = parseInt($.cookie("test_captcha"));
_this.doTimer();//执行倒计时
}
//点击获取验证码 开始做倒计时
$(".getCode").click(function () {
if ($(this).hasClass("getCode")) {//切换类名实现防止多次连续点击
_this.remainder = _this.spacing;
_this.doTimer();//执行倒计时
}
})
},
methods: {
doTimer: function () {//执行倒计时
var _this = this;
_this.timer = setInterval(function () {
_this.remainder--;
if (_this.remainder > 0) {
$.cookie("test_captcha", _this.remainder, { "expires": ((1 / 86400) * _this.remainder) });
//$.cookie("test_captcha", _this.remainder); //不设置失效时间,就是只要用户关闭浏览器就会失效
} else {
clearInterval(_this.timer);
_this.timer = null;
}
}, 1000);
},
}
});
cookie_downTime.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<title>cookie做倒计时</title>
<style>
[v-cloak]{
display:none!important;
}
.codeBtn{
width:140px;
height:40px;
line-height:40px;
text-align:center;
margin:auto;
border-radius:6px;
background:#23A9F2;
color:#fff;
}
.showDownTime{
background:#ddd;
color:#333;
}
</style>
</head>
<body>
<div id="vm" v-cloak>
<div :class="['codeBtn',remainder > 0 ? 'showDownTime' : 'getCode']">{{remainder > 0 ? remainder + 's' : '获取验证码'}}</div>
</div>
<script src="./cookie_downTime.js"></script>
</body>
</html>
分割线--------------------------------------------------------------------------------------------------------分割线
以下内容为使用原生js操作cookie,与以上例子无关
1、获取cookie(如果设置了httpOnly是获取不到的,可降低XSS攻击风险)
// 获取指定名称的cookie
function getCookie(name){
var strcookie = document.cookie; // 获取cookie字符串
var arrcookie = strcookie.split("; "); // 分割
//遍历匹配
for ( var i = 0; i < arrcookie.length; i++) {
var arr = arrcookie[i].split("=");
if (arr[0] == name){
return arr[1];
}
}
return "";
}
// 打印所有cookie
function printAllCookie() {
var strcookie = document.cookie; // 获取cookie字符串
var arrcookie = strcookie.split(";"); // 分割
// 遍历匹配
for ( var i = 0; i < arrcookie.length; i++) {
var arr = arrcookie[i].split("=");
console.log(arr[0] + ":" + arr[1]);
}
}
2、设置cookie(expires值是失效时间点,没设置的话就是浏览器关闭的时候失效)
// 不给expires值,浏览器关闭就失效
document.cookie = "setCookie=yes";
// 设置7天后失效
var date = new Date(); // 获取当前时间
date.setTime(date.getTime() + (7 * 24 * 60 * 60 * 1000)); // 将date设置为7天后
document.cookie = "setCookie1=yes; expires=" + date.toGMTString();
document.cookie = "setCookie2=no; expires=" + date.toGMTString();
3、删除cookie(通过设置失效时间点在此刻之前即可)
// 设置失效时间点在此刻之前
var date = new Date(); // 获取当前时间
date.setTime(date.getTime() - 1);
document.cookie = "setCookie1=cancle; expires=" + date.toGMTString();
document.cookie = "setCookie2=cancle; expires=" + date.toGMTString();