ThinkPHP防止重复提交表单的方法实例分析


Posted in PHP onMay 10, 2018

本文实例总结分析了ThinkPHP防止重复提交表单的方法。分享给大家供大家参考,具体如下:

为什么会有表单重复的坑

在开发中,如果一个新增或修改的表单,在后台完成数据库操作后我们设定的不是跳转到其他页面,还是返回本页面,这时点击浏览器的后退再提交或刷新页面,会导致form表单重复提交,即这条记录会被增加或修改两次。

导致表单重复提交的原因是:第一次提交的表单会被缓存到内存中,直到页面下次提交或页面关闭或转向其他页面时才消失。在自调用返回时,内存中的数据依然在,这时页面中的判断提交的代码依然可以检测到提交的值,顾会产生重复提交的效果。

如何解决?

总结网上的解决办法和自己的测试,可以用以下几个办法:

方法1:最简单:页面提交后转到另一个页面而不是本页面,举个栗子,比如你的页面地址为

http://yourdomain.com/User/Index/login

则该页面的表单action地址可以为另外的处理地址,如

<form action="{:U('User/Index/check_login')}" method="post">

这样报错返回,或者用户点击回退按钮,还是会回到上一个地址,不过这种情况也不保险。还要搭配方法2,一起比较保险

方法2:提交表单后提交按钮变灰/隐藏提交按钮

这种方式一般是结合方法1来做的,通过JS来动态监听用户的点击动作,动态将按钮属性置成disabeld,即为灰色不可用。代码如下:

HTML:

<form action="{:U('User/Index/check_login')}" method="post">
  <input type="text" name="username" value="" id="username" />
  <input type="password" name="userpwd" id="userpwd" />
  <input type="submit" name="login_btn" id="login_btn" value="登陆"/>
</form>

JS:

$().ready(function(){
   $("#login_btn").on('click',function(){
      $(this).attr('disabled',true);
   });
});

方法1+方法2 结合后,基本上90%以上的重复提交问题都能解决,但是大刘这里还是要说下第三种方法,即在服务端一劳永逸的解决这个问题

方法3:使用隐藏随机TOKEN值的方法进行重复提交判断

首先,在项目的functions.php中添加如下方法

//创建TOKEN
function createToken() {
  $code = chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) .    chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) . chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE));
  session('TOKEN', authcode($code));
}
//判断TOKEN
function checkToken($token) {
  if ($token == session('TOKEN')) {
    session('TOKEN', NULL);
    return TRUE;
  } else {
   return FALSE;
  }
}
/* 加密TOKEN */
function authcode($str) {
  $key = "YOURKEY";
  $str = substr(md5($str), 8, 10);
  return md5($key . $str);
}

在表单页面form中填入以下HTML代码

HTML:

<input type="hidden" name="TOKEN" value="{:session('TOKEN')}" />

在页面展示前调用creatToken()方法生成token,在相应控制器POST请求中 使用 checkToken() 进行判断是否重复提交

if(IS_POST)
{
$post_token = I('post.TOKEN');
 if(!checkToken($post_token)){
   $this->error('请不要重复提交页面',U('User/Index/login'));
 }
}

基本上,这3个方法配合着使用,就能解决ThinkPHP开发中表单重复提交问题,当然,有同学说可以使用ThinkPHP的令牌环机制,这样其实就更简单了,TP会默认在表单中生成一个隐藏域,到时候判断这个隐藏域是否存在以及和session中的值是否想的即可,原理和方法3是一样的。

PS:今天终于把内容用简书的markdown编辑器发出来了,果然markdown语法不是盖的,整个排版都清爽了,不错不错。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP+MYSQL的文章管理系统(一)
Oct 09 PHP
如何写php程序?
Dec 08 PHP
Zend Guard一些常见问题解答
Sep 11 PHP
PHP数组内存耗用太多问题的解决方法
Apr 05 PHP
php获取当前网址url并替换参数或网址的方法
Jun 06 PHP
处理(php-cgi.exe - FastCGI 进程超过了配置的请求超时时限)的问题
Jul 03 PHP
php实现上传图片生成缩略图示例
Apr 13 PHP
护卫神php套件 php版本升级方法(php5.5.24)
May 10 PHP
thinkphp的dump函数无输出实例代码
Nov 15 PHP
PHP实现根据数组的值进行分组的方法
Apr 20 PHP
php实现的错误处理封装类实例
Jun 20 PHP
Laravel 错误提示本地化的实现
Oct 22 PHP
PHP实现用户登录的案例代码
May 10 #PHP
yii2多图上传组件的使用教程
May 10 #PHP
PHP数组去重的更快实现方式分析
May 09 #PHP
PHP+MySQL实现消息队列的方法分析
May 09 #PHP
PHP共享内存使用与信号控制实例分析
May 09 #PHP
php curl批处理实现可控并发异步操作示例
May 09 #PHP
php使用curl伪造来源ip和refer的方法示例
May 08 #PHP
You might like
PHP中SESSION使用中的一点经验总结
2012/03/30 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
详解PHP+AJAX无刷新分页实现方法
2015/11/03 PHP
js几个不错的函数 $$()
2006/10/09 Javascript
让textarea控件的滚动条怎是位与最下方
2007/04/20 Javascript
基于jquery自定义图片热区效果
2012/07/21 Javascript
jquery等宽输出文字插件使用介绍
2013/09/18 Javascript
form.submit()不能提交表单的原因分析
2014/10/23 Javascript
javascript继承机制实例详解
2014/11/20 Javascript
JavaScript使用slice函数获取数组部分元素的方法
2015/04/06 Javascript
js限制文本框的输入内容代码分享(3类)
2015/08/20 Javascript
jquery实现全选、不选、反选的两种方法
2016/09/06 Javascript
Vue服务端渲染和Vue浏览器端渲染的性能对比(实例PK )
2017/03/31 Javascript
JavaScript设置名字输入不合法的实现方法
2017/05/23 Javascript
Vue源码学习之初始化模块init.js解析
2017/11/02 Javascript
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
2018/08/02 Javascript
浅谈在Vue.js中如何实现时间转换指令
2019/01/06 Javascript
在 Vue.js中优雅地使用全局事件的方法
2019/02/01 Javascript
JS实现移动端在线签协议功能
2019/08/22 Javascript
多个vue子路由文件自动化合并的方法
2019/09/03 Javascript
解决Echarts 显示隐藏后宽度高度变小的问题
2020/07/19 Javascript
mustache.js实现首页元件动态渲染的示例代码
2020/12/28 Javascript
解读Python编程中的命名空间与作用域
2015/10/16 Python
python的exec、eval使用分析
2017/12/11 Python
提升Python程序性能的7个习惯
2019/04/14 Python
python多线程同步之文件读写控制
2021/02/25 Python
Python 模拟动态产生字母验证码图片功能
2019/12/24 Python
在django admin中配置搜索域是一个外键时的处理方法
2020/05/20 Python
Python变量及数据类型用法原理汇总
2020/08/06 Python
python如何运行js语句
2020/09/09 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
2020/11/24 Python
python Zmail模块简介与使用示例
2020/12/19 Python
委托证明的格式
2014/01/10 职场文书
安全生产投入制度
2014/01/29 职场文书
高中团支书竞选稿
2015/11/21 职场文书