JSP学习之------>客户端防表单重复提交和服务器端session防表单重复提交
2023-09-27 14:29:34 时间
1.什么叫表单重复提交:
所谓表单重复提交,是指用户通过多次点击提交按钮或多次刷新表单提交页面等造成用户表单重复提交的现象
2.表单重复提交有哪些情况:
(1)用户在程序提交表单的时间段里多次提交表单
(2)重复刷新提交后的表单
(3)用户点击浏览器回退按钮,然后再次提交
3.如果解决表单重复提交:
(1)方法1:客户端防表单重复提交: 一般通过js代码防止第一种情况的发生,对于第二种和第三种的情况很难避免,并且稍微有经验的用户可以通过去掉页面js生成自己的html页面来访问服务器,这样客户端的防表单重复提交只能“防君子不能防小人”,并且可以增强用户体验感。
(2)方法2:服务器端session防表单重复提交:一般是利用令牌的原理来实现表单重复提交的,具体做法:
A. 对于用户每一次访问表单页面,均先经过CreateFormServlet的Servlet,其作用是在跳转表单页面之前,由BASE64Encoder类生成一个唯一的字符串,即表单号,并保存在session域中.
B.然后用户提交表单时,带着表单号,先验证客户端提交过来的表单号和session域中的表单号是否相同,如果不同则证明是重复提交,如果相同,则证明是第一次提交,并将表单号从session域中移除。
4.例子程序:
regist.jsp
scripttype="text/javascript" /*虽然客户端防表单重复提交,有很多漏洞,但是为了提高客户体验感,一把是客户端和服务器配合防表单重复提交, 客户端防重复提交的漏洞:1.客户复制源代码,去掉此js脚本,生成自己的html页面,然后提交 2.重复刷新提交后的表单 3.用户点击浏览器回退按钮,然后再次提交 客户端防重复提交的代码: 1.方法1: var isCommited =false; function dosubmit(){ if(!isCommited){ isCommited = true; return true; }else{ return false; } } */ //或者使"注册"按钮点击一次后不可用 function dosubmit1(){ var input = document.getElementById("submit"); input.disabled="disabled"; return true; } /script body formaction="/CookieAndSession/servlet/regist"method="post"onsubmit="return dosubmit()" 用户名: inputtype="text"name="username"value="aaa" br/ inputtype="hidden"name="c_token"value="${token}" inputid="submit"type="submit"value="注册" /form /body /html
script type="text/javascript" /*虽然客户端防表单重复提交,有很多漏洞,但是为了提高客户体验感,一把是客户端和服务器配合防表单重复提交, 客户端防重复提交的漏洞:1.客户复制源代码,去掉此js脚本,生成自己的html页面,然后提交 2.重复刷新提交后的表单 3.用户点击浏览器回退按钮,然后再次提交 客户端防重复提交的代码: 1.方法1: var isCommited = false; function dosubmit(){ if(!isCommited){ isCommited = true; return true; }else{ return false; //或者使"注册"按钮点击一次后不可用 function dosubmit1(){ var input = document.getElementById("submit"); input.disabled="disabled"; return true; /script body form action="/CookieAndSession/servlet/regist" method="post" onsubmit="return dosubmit()" 用户名: input type="text" name="username" value="aaa" br/ input type="hidden" name="c_token" value="${token}" input id="submit" type="submit" value="注册" /form /body /html CreateFormServlet.java url-pattern: /servlet/createform
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sun.misc.BASE64Encoder; public class CreateFormServletextends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //产生表单号
request.getSession().setAttribute("token", token); request.getRequestDispatcher("/regist.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } class TokenProcessor{ private static TokenProcessor token =new TokenProcessor(); private TokenProcessor(){} public static TokenProcessor getInstance(){ return token; } 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); } }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sun.misc.BASE64Encoder; public class CreateFormServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //产生表单号 String token = TokenProcessor.getInstance().generateToken(); request.getSession().setAttribute("token", token); request.getRequestDispatcher("/regist.jsp").forward(request, response); public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); class TokenProcessor{ private static TokenProcessor token = new TokenProcessor(); private TokenProcessor(){} public static TokenProcessor getInstance(){ return token; 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); RegistServlet.java url-pattern: /servlet/regist
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegistServletextends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); boolean isValid = tokenValidate(request); if(!isValid){ out.print(" script alert(请不要重复提交,程序正在处理!); /script "); return ; } out.println("正在向数据库注册用户信息!"); } private boolean tokenValidate(HttpServletRequest request) { String c_token = request.getParameter("c_token"); String s_token = (String) request.getSession().getAttribute("token"); //防止用户自定义html if(c_token==null) return false; if (s_token==null) return false; if (!s_token.equals(c_token)) return false; request.getSession().removeAttribute("token"); return true; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegistServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); boolean isValid = tokenValidate(request); if(!isValid){ out.print(" script alert(请不要重复提交,程序正在处理!); /script return ; out.println("正在向数据库注册用户信息!"); private boolean tokenValidate(HttpServletRequest request) { String c_token = request.getParameter("c_token"); String s_token = (String) request.getSession().getAttribute("token"); //防止用户自定义html if(c_token==null) return false; if (s_token==null) return false; if (!s_token.equals(c_token)) return false; request.getSession().removeAttribute("token"); return true; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); 程序不能直接进入regist.jsp页面,只能通过http://localhost:8080/CookieAndSession/servlet/createform进入CreateFormServlet.java通过此Servlet跳转至注册页面
此时http://localhost:8080/CookieAndSession/servlet/createform页面原代码如下:
这样就可以解决以上三种可能出现的表单重复提交问题!
字节卷动 You will never know how excellent you are unless you impel yourself once.
相关文章
- Leetcode: Sum of Two Integers && Summary: Bit Manipulation
- 用L脚本语言实现"L脚本语言控制台"
- V3 - 现在完成时(present perfect) & 一般过去时(past) 区别和差异 Teacher:Lamb
- 微服务技术系列教程(33) - SpringCloud-消息驱动简介&原理
- ECC & HSTS preload List
- Go语言开发小技巧&易错点100例(四)
- Build 2015 Beijing & Windows 10 China Geek Challenge
- 3 Steps to Perform SSH Login Without Password Using ssh-keygen & ssh-copy-id
- 关于javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>
- 技术男的春天:小姐姐求助&暖男分析
- poj 3259 Wormholes 【SPFA&&推断负环】
- <模拟电子学习1>Multisim 12.0 结构和仿真51最小的单芯片系统
- DICOM医学图像处理:深入剖析Orthanc的SQLite,了解WADO & RESTful API
- IDEA 教程之基础篇(六):IntelliJ IDEA 中创建 Web 项目 & 配置 Tomcat