客户端服务端防止用户重复提交表单
来源:互联网 发布:linux命令 system dd 编辑:程序博客网 时间:2024/05/11 23:48
一、什么是表单重复提交?
当网络有延迟时,用户提交的表单等数据还没有完成此次提交,但用户又多次点击提交,造成用户数据在数据库或存储中被提交多次。
利用线程延迟,简单模拟重复提交。
表单页面为form.html
[html] view plain copy
form.html
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
用户名 :
处理提交请求的servlet为DoFormServlet.java
[java] view plain copy
package SessionDemo;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DoFormServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); //利用线程休眠,模拟网络延迟 try { Thread.sleep(1000*3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("向数据库中注册数据。"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
在浏览器中加载form.html
当用户反复点击“提交”时,就造成了重复提交。
二、解决方法一:利用javascript阻止
其他不变,将form.html修改为
[html] view plain copy
form.html
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
var isCommitted = false;
function dosubmit()
{
if(!isCommitted)
{
isCommitted=true;
return true;
}
else
{
return false;
}
}
用户名 :
这样在浏览器中加载form.html后,点击“提交”,终端中只会输出一次”向数据库中注册数据。”,表明成功阻止表单反复提交。
以上form.html可以进一步优化,当用户点击“提交”后,“提交”按钮应该变为灰色不可用。
[html] view plain copy
form.html
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
function dosubmit()
{
var input = document.getElementById("submit");
input.disabled = 'disabled';
return true;
}
用户名 :
利用javascript的方法不能完全防止用户恶意重复提交,例如:用户可以将form.html保存后修改,还可以在点击“提交”后重复刷新页面,从而实现反复提交。
三、解决方法二:利用服务器端Session防止表单重复提交。
其中FormServlet.java为
[java] view plain copy
package SessionDemo;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Encoder;
public class FormServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //产生随机数表单号 TokenProcessor tp = TokenProcessor.getInstance(); String token = tp.generateToken(); request.getSession().setAttribute("token",token); request.getRequestDispatcher("/form.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
//设计为单例模式
class TokenProcessor
{
private TokenProcessor(){};
private static final TokenProcessor instance = new TokenProcessor();
public static TokenProcessor getInstance() { return instance; } public String generateToken() { //获得随机数字符串 String token = System.currentTimeMillis() + new Random().nextInt() + ""; //获得数据摘要 try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] md5 = md.digest(token.getBytes()); //利用base64编码防止乱码。 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(md5); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
}
添加form.jsp
[plain] view plain copy
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8”%>
用户名
将DoFormServlet.java修改为
[java] view plain copy
package SessionDemo;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DoFormServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); boolean b = isTokenValue(request); if (!b) { System.out.println("请不要重复提交。"); return; } request.getSession().removeAttribute("token"); System.out.println("向数据库中注册数据。"); } //判断表单号是否有效 private boolean isTokenValue(HttpServletRequest request) { String clientToken = request.getParameter("token"); if(clientToken==null) { return false; } String serverToken = (String) request.getSession().getAttribute("token"); if(serverToken==null) { return false; } if (!clientToken.equals(serverToken)) { return false; } return true; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
再浏览器中加载FormServlet
点击“提交”后跳转
终端显示用户提交
这时即使用户点击“刷新”,也不能实现重复提交。
- 客户端服务端防止用户重复提交表单
- 防止用户表单重复提交
- 防止表单的重复提交(服务端)
- 防止表单的重复提交(客户端)
- 客户端、服务器端防止表单重复提交
- 如何防止用户后退重复提交表单?
- 防止用户后退重复提交表单
- 如何防止用户后退重复提交表单
- Struts1.x 防止用户重复提交表单
- struts防止用户重复提交表单
- 如何防止用户重复提交表单
- session实现防止用户重复提交表单
- dwr防止注册用户重复,并防止表单提交
- 防止表单重复提交
- 防止重复提交表单
- 防止表单重复提交
- 防止表单重复提交
- 防止表单重复提交
- VMWare虚拟机设置固定IP上网方法
- Tensorflow运行中出现ImportError: No module named input_data报错信息的解决方法
- Mac 10.12.6 install | 寨板x79+E5-2670+AMD HD-7850 | Win10+Mac 双系统
- POJ 2774 后缀数组
- 自己画的流程图,舍不得删,保存下
- 客户端服务端防止用户重复提交表单
- Hibernate与Mybatis对比
- 光环国际PMP:项目经理的“三边六拍”
- PHP开发环境部署(LAMP WAMP)
- Android之提升App启动速度
- 数组扁平化和去重
- python UnicodeDecodeError: 'ascii' codec can't decode byte ...
- NKOJ 3985 (HNOI 2012) 矿场搭建(Tarjan求割点)
- 取消鼠标拖动选中文字的方法