如何在Laravel Blade页面实时显示每秒变化的验证码剩余时间
解决方案
1. 后端传递验证码过期时间戳到视图
在返回验证页面的控制器方法中,从Session取出codeSent(需为Carbon实例),转换为秒级Unix时间戳后传递给Blade视图:
public function showVerificationForm() { $expirationTime = session('codeSent'); $expirationTimestamp = $expirationTime ? $expirationTime->getTimestamp() : null; return view('auth.verify', compact('expirationTimestamp')); }
2. Blade模板嵌入时间戳并准备倒计时容器
在模板中将时间戳存入DOM元素的data属性,同时创建倒计时显示容器:
<div class="code-countdown" data-expires="{{ $expirationTimestamp }}"> 验证码剩余时间:<span id="timer-display"></span> </div>
3. 前端JS实现实时倒计时逻辑
通过JavaScript读取过期时间戳,每秒计算并更新剩余时间,同时处理过期后的状态:
document.addEventListener('DOMContentLoaded', function() { const countdownContainer = document.querySelector('.code-countdown'); const timerDisplay = document.getElementById('timer-display'); const expiresAt = parseInt(countdownContainer.dataset.expires); if (!expiresAt) { timerDisplay.textContent = '请先获取验证码'; return; } const updateCountdown = () => { const currentTime = Math.floor(Date.now() / 1000); const remainingSeconds = expiresAt - currentTime; if (remainingSeconds <= 0) { timerDisplay.textContent = '验证码已过期'; clearInterval(countdownInterval); // 可选:启用重新发送按钮 document.getElementById('resend-code-btn')?.removeAttribute('disabled'); return; } const minutes = Math.floor(remainingSeconds / 60); const seconds = remainingSeconds % 60; timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; }; // 立即执行一次避免初始延迟 updateCountdown(); // 每秒更新倒计时 const countdownInterval = setInterval(updateCountdown, 1000); });
额外说明
- 时区兼容性:后端Carbon的
getTimestamp()和前端Date.now()均基于UTC时间戳,差值计算不受客户端时区影响,结果准确。 - 页面刷新处理:刷新页面后,JS会重新读取Session传递的时间戳初始化倒计时,无需额外逻辑。
- 重新发送场景:用户点击重新发送验证码后,后端更新Session中的
codeSent,前端可通过AJAX请求成功后更新data-expires属性,或直接刷新页面重置倒计时。
内容的提问来源于stack exchange,提问作者Pouya Vaghefi
相关产品推荐
相关产品推荐

