跳转到主内容
极星编程网:以代码为星,赴技术山海!

ThinkPHP如何防止表单重复提交_表单token与session校验【教程】

ThinkPHP防重复提交核心是服务端一次性Token+Session绑定+立即销毁闭环。需显式生成Token并嵌入表单,提交时严格校验并立即清除Session中Token,成功后必须重定向跳转,前端禁用按钮仅为体验优化。 ThinkPHP 防重复提交不能只靠前端禁用按钮或数据库唯一索引,核心是「服务端一次性 Token + Session 绑定 + 立即销毁」的闭环。Token 必须生成、嵌入、校验、清空四步到位,缺一不可。 表单页:正确生成并嵌入 Token Token 不是配置打开就自动生效,必须显式生成并写入表单。ThinkPHP 6.x 推荐两种方式: 使用内置模板标签:
{__token__/}
(V6.1+ 默认不启用,需在
config/app.php
中设
'token_on' => true
); 手动控制更稳妥:控制器中调用
$this->assign('token', Str::random(32))
,再存入 Session:
session('submit_token', $token)
; 模板中写成:
,字段名保持与后端校验一致。 提交时:严格校验并立即销毁 Token 校验不是可选步骤,而是业务逻辑执行前的第一道闸门: 必须用
===
严格比对,避免类型转换绕过(如
"0" == false
); 校验通过后第一件事是
session('submit_token', null)
或
session()->delete('submit_token')
,不是赋空字符串或留着不管; 若用验证器,
__token
字段默认不进
$data
,需单独提取:
$data['__token'] = $this->request->param('__token')
,否则规则不触发; 更推荐启用中间件
think\middleware\Token
,并在路由中注册,由框架统一拦截非法请求。 跳转后:防止刷新重发 POST 请求 用户提交成功后按 F5 刷新,浏览器会重发原始 POST —— 这是 PRG(Post-Redirect-Get)没做完整的表现: PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 立即学习 “ PHP免费学习笔记(深入) ”; 控制器处理完必须用
return redirect('/success')
跳转,不能直接
return $this->fetch()
返回当前页; 前端可辅助增强:跳转后执行
history.replaceState({}, '', location.href)
,把表单页从历史栈中替换掉; 表单页加载时检测是否为刷新进入:
if (performance.navigation?.type === 1) { document.querySelector('form').reset(); }
,清空表单并禁用按钮。 前端配合:禁用按钮只是体验优化,不是防重主力 按钮禁用能减少误点,但绕过 JS 极其容易,绝不能替代后端校验: 用
form.addEventListener('submit', e => { e.preventDefault(); btn.disabled = true; ... })
统一入口; 禁用同时改文案为「提交中…」,避免用户因无反馈而狂点; AJAX 提交务必在
finally
中恢复按钮状态,不能只在
then
或
catch
里处理; 不要用
onclick="return false"
这类粗暴写法,它不响应回车提交和屏幕阅读器等辅助操作。

相关文章