倒计时按钮必须同步禁用与更新文案,两者为原子操作;需用localStorage持久化剩余时间防刷新漏洞;倒计时与短信发送结果解耦,后端失败须主动重置状态;禁用定时器并清理内存泄漏。
倒计时按钮必须同步禁用与更新文案
只改文字不禁用,用户能连点多次触发重复请求;只禁用不更新文字,用户不知道还剩几秒。两者必须原子性操作。
- 用
setAttribute("disabled", "true")或 jQuery 的prop("disabled", true)禁用按钮 - 同时调用
text()(jQuery)或innerText(原生)更新文案,例如"60s 后重发" - 倒计时归零后,必须
removeAttribute("disabled")或prop("disabled", false)恢复可点击状态 - 务必调用
clearInterval(InterValObj)清除定时器,否则内存泄漏且后续倒计时错乱
刷新后倒计时丢失?用 localStorage 持久化剩余时间
默认页面刷新,count 变量重置为 60,用户刚点完就刷新,又能立刻再点——这在防刷场景下是严重漏洞。
- 倒计时开始时写入:
localStorage.setItem("smsCountdown", 60) - 页面加载时检查:
const saved = localStorage.getItem("smsCountdown"),若存在且> 0,则立即启动对应秒数倒计时 - 每次递减都同步更新:
localStorage.setItem("smsCountdown", curCount) - 归零后执行:
localStorage.removeItem("smsCountdown") - 不用 cookie,除非后端强制要求跨域校验;
localStorage更轻量、API 更直观
别把倒计时和短信发送结果混为一谈
前端倒计时只是 UI 防抖,不代表后端短信已发出或成功。后端返回失败时,必须主动重置倒计时状态,否则按钮被“假锁定”。
- 后端返回发送失败(如手机号格式错误、频次超限),应立即执行:
localStorage.removeItem("smsCountdown") - 恢复按钮:
$("#btnSendCode").prop("disabled", false).text("获取验证码") - 不要等倒计时自然归零才处理失败响应——用户可能卡在 59 秒不动,但实际请求早已失败
- 倒计时逻辑和 AJAX 成功回调解耦:倒计时启动不依赖请求是否成功,请求失败也不影响倒计时继续跑(除非你主动干预)
formX.startTimer 是第三方扩展,不是 layui 原生模块
文档里写的 formX.startTimer 不是 layui 官方 API,未引入会报 formX is not defined 错误。
- 必须先通过
layui.use(['formX'], function() {...})显式声明依赖 - 该方法内部仍是基于
setInterval封装,适合快速原型,但定制能力弱(比如加 loading 图标、失败后重置文案等) - 自定义文案函数中,
return time + 's 后可继续发送'必须确保time是数字类型,否则输出"NaNs 后可继续发送" - 生产环境建议优先用原生
setInterval+localStorage组合,可控性强、无额外依赖


















