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 session和cookie使用说明
Apr 07 PHP
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
Oct 12 PHP
解析PHP中的file_get_contents获取远程页面乱码的问题
Jun 25 PHP
单台服务器的PHP进程之间实现共享内存的方法
Jun 13 PHP
PHP源码分析之变量的存储过程分解
Jul 03 PHP
PHP字符串比较函数strcmp()和strcasecmp()使用总结
Nov 19 PHP
php判断当前用户已在别处登录的方法
Jan 06 PHP
php通过淘宝API查询IP地址归属等信息
Dec 25 PHP
thinkPHP3.1验证码的简单实现方法
Apr 22 PHP
php生成无限栏目树
Mar 16 PHP
Laravel学习教程之View模块详解
Sep 18 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
Feb 03 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数据库类
2009/05/27 PHP
PHP iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
PHP获取文件相对路径的方法
2015/02/26 PHP
Yii框架上传图片用法总结
2016/03/28 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
2016/09/21 PHP
php7 错误处理机制修改实例分析
2020/05/25 PHP
JQuery从头学起第三讲
2010/07/06 Javascript
js带缩略图的图片轮播效果代码分享
2015/09/14 Javascript
深入分析Javascript事件代理
2016/01/30 Javascript
基于jQuery实现表格的排序
2016/12/02 Javascript
ES2015 Symbol 一种绝不重复的值
2016/12/25 Javascript
最基础的vue.js双向绑定操作
2017/08/23 Javascript
[js高手之路]从原型链开始图解继承到组合继承的产生详解
2017/08/28 Javascript
jQuery实现的form转json经典示例
2017/10/10 jQuery
webpack的tree shaking的实现方法
2019/09/18 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
js+canvas实现五子棋小游戏
2020/08/02 Javascript
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
[52:12]FNATIC vs Infamous 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
[57:29]Alliance vs KG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/17 DOTA
利用python将json数据转换为csv格式的方法
2018/03/22 Python
Python实现的txt文件去重功能示例
2018/07/07 Python
python将txt文件读取为字典的示例
2018/12/22 Python
手把手教你使用Python创建微信机器人
2019/04/29 Python
pyinstaller打包单个exe后无法执行错误的解决方法
2019/06/21 Python
Django 对IP访问频率进行限制的例子
2019/08/30 Python
CSS3教程(2):网页边框半径和网页圆角
2009/04/02 HTML / CSS
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
data:image data url 文件转为Blob上传后端的方法
2019/07/16 HTML / CSS
h5移动端调用支付宝、微信支付的实现
2020/06/08 HTML / CSS
ASICS印度官方网站:日本专业运动品牌
2020/06/20 全球购物
应届大专毕业生个人自荐信
2013/09/22 职场文书
网络技术专业求职信
2014/02/18 职场文书
教师学期末个人总结
2015/02/13 职场文书
PyQt5爬取12306车票信息程序的实现
2021/05/14 Python
详解apache编译安装httpd-2.4.54及三种风格的init程序特点和区别
2022/07/15 Servers