客户端防表单重复提交和服务器端session防表单重复提交
来源:互联网 发布:如何管理淘宝 编辑:程序博客网 时间:2024/06/06 02:58
IT程序员开发必备-各类资源下载清单,史上最全IT资源,个人收藏总结!
所谓表单重复提交,是指用户通过多次点击提交按钮或多次刷新表单提交页面等造成用户表单重复提交的现象
2.表单重复提交有哪些情况:
(1)用户在程序提交表单的时间段里多次提交表单
(2)重复刷新提交后的表单
(3)用户点击浏览器回退按钮,然后再次提交
3.如果解决表单重复提交:
(1)方法1:客户端防表单重复提交: 一般通过js代码防止第一种情况的发生,对于第二种和第三种的情况很难避免,并且稍微有经验的用户可以通过去掉页面js生成自己的html页面来访问服务器,这样客户端的防表单重复提交只能“防君子不能防小人”,并且可以增强用户体验感。
(2)方法2:服务器端session防表单重复提交:一般是利用令牌的原理来实现表单重复提交的,具体做法:
A. 对于用户每一次访问表单页面,均先经过CreateFormServlet的Servlet,其作用是在跳转表单页面之前,由BASE64Encoder类生成一个唯一的字符串,即表单号,并保存在session域中.
B.然后用户提交表单时,带着表单号,先验证客户端提交过来的表单号和session域中的表单号是否相同,如果不同则证明是重复提交,如果相同,则证明是第一次提交,并将表单号从session域中移除。
4.例子程序:
regist.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><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
package edu.form;import java.io.IOException;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 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
package edu.form;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 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页面原代码如下:
这样就可以解决以上三种可能出现的表单重复提交问题!
- 客户端防表单重复提交和服务器端防重复提交
- 客户端防表单重复提交和服务器端session防表单重复提交
- 客户端防表单重复提交和服务器端session防表单重复提交
- JSP学习之------>客户端防表单重复提交和服务器端session防表单重复提交
- 客户端防表单重复提交和服务器端session防表单重复提交
- 客户端防表单重复提交和服务器端Session防表单重复提交
- java_客户端防表单重复提交和服务器端session防表单重复提交
- 客户端防表单重复提交和服务器端session防表单重复提交
- 客户端防表单重复提交和服务器端session防表单重复提交
- 客户端防表单重复提交和服务器端session防表单重复提交
- JAVAWeb_利用Session防止表单重复提交:10-客户端防表单重复提交和服务器端session防表单重复提交
- JAVAWeb_利用Session防止表单重复提交:10-客户端防表单重复提交和服务器端session防表单重复提交
- 2.客户端防表单重复提交和服务器端防表单重复提交
- javaweb之Session客户端防表单重复提交(js)和服务端Session防表单重复提交
- 客户端和服务器端防表单重复提交的策略
- 防表单重复提交
- 防表单重复提交
- 防表单重复提交
- mac ubuntu_server 常用命令
- ubuntu配置Android sdk
- 怎样才能写个好简历?
- ubuntu配置Android sdk 出现问题 权限不够
- nodejs下载文件
- 客户端防表单重复提交和服务器端session防表单重复提交
- mac下命令行调用chrome
- ubuntu编写开机自启动shell脚本
- mongoDB 数据库备份与恢复
- node.js npm的安装(安装forever)
- express拖拽文件上传,XMLHttpRequest(),服务器端处理详解
- shell编程基础自学知识(截取字符串) shell基础语法判断和循环等
- date 命令使用小技巧
- crontab 定时执行shell脚本