客户端和服务器后退操作防止表单重复提交
来源:互联网 发布:视频爬虫 python 编辑:程序博客网 时间:2024/06/06 05:43
表单重复提交的情况大体有两种:一种是网速卡,造成表单没有提交的假象,用户不停的点击提交。另一种则是用户的故意操作,后退或刷新页面然后重新提交。要做的就是防止这两种情况的表单重复提交。
防止第一种,我们可以在客户端添加操作防止现象发生,有两种方式,都是通过javascript实现的。第一种方式是在javascript中设置一个变量。初值为false,点击提交按钮之后将变量改为true,并且,在变量为false时按钮有提交作用。代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>ReapteForm.html</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript"> var competeSign = false; function check() { if(!competeSign) { competeSign = true; return competeSign; }else { alert("不能重复提交表单"); return false; } } </script> </head> <body style="background-color: white;"> <form action="/learnJS/servlet/RepeateFormServlet" method="post" onsubmit="return check()"> 留言内容:<br/> <textarea rows="10" cols="50"></textarea><br/> <input type="submit" value="提交"/> </form> </body></html>
javascript的第二种方式是,在按钮点击之后变为不可用,这样就不能再提交啦。代码为:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript"> function dosubmit() { var input = document.getElementById("submit"); input.disabled = 'disabled'; return true; } </script> </head> <body style="background-color: white;"> <form action="/learnJS/servlet/RepeateFormServlet" method="post" onsubmit="return dosubmit();"> 留言内容:<br/> <textarea rows="10" cols="50"></textarea><br/> <input type="submit" id="submit" value="提交"/> </form> </body></html>再有就是在服务器端通过session方式防止表单的重复提交,这样只能防止后退操作,不能防止刷新操作的。思路是,在页面的表单中有一个隐藏项,每一个表单都有一个唯一的标号,同时session中设置一个属性域,通过标号和属性域的比对操作,确定表单是否为重复提交。页面代码为:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@page import="com.you.learn.TokenProcessor"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>FormGenerate.jsp</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript"> function beformsubmit() { var p1 = document.getElementById("p1").value; if(p1==""){ alert("请输入内容!"); return false; } return true; } </script> </head> <body style="background-color: white;"> <% TokenProcessor.getInstance().saveToken(request); String token = (String)request.getSession().getAttribute(TokenProcessor.FORM_TOKEN_KEY); String name = TokenProcessor.FORM_TOKEN_KEY; System.out.println("html:" + token); %> <form action="/learnJS/servlet/FormDealServlet" method="post" onsubmit="return beformsubmit();"> <input type="hidden" name="<%=name %>" value="<%=token %>"> 字段1:<input type="text" name="p1" id="p1"/><br/> <input type="submit" value="提交"/> </form> </body></html>
处理页面的servlet页面代码为:
package com.you.servlet;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;import com.you.learn.TokenProcessor;public class FormDealServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();request.getParameter("TokenProcessor.FORM_TOKEN_KEY");TokenProcessor tokenProcessor = TokenProcessor.getInstance();if(!tokenProcessor.isTokenValid(request)) {out.println("这是重复或非法提交!");response.sendRedirect("/learnJS/FormGenerate.jsp");return;}String p1 = request.getParameter("p1");if(p1 == null || p1.trim().equals("")) {out.println("请输入内容!");}else {out.println("提交内容已被处理!");tokenProcessor.resetToken(request);}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
还有一个Java工具类,用于生成标号:
package com.you.learn;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import sun.misc.BASE64Encoder;public class TokenProcessor {private long previous;//上次生成表单标识号的时间值private static TokenProcessor instance = new TokenProcessor();public static String FORM_TOKEN_KEY = "FORM_TOKEN_KEY";private TokenProcessor() {}@SuppressWarnings("unused")public static TokenProcessor getInstance() {return instance;}/* * 验证请求消息中的标识号是否有效,如果验证请求消息中的标识号和 * 用户session域中的标识号相同,返回结果为true,否则返回false * */public synchronized boolean isTokenValid(HttpServletRequest request) {/* * 为避免session对象不存在时创建session对象, * 下面的语句不用request.getSession() */HttpSession session = request.getSession(false);if(session == null) {return false;}String saved = (String)request.getSession().getAttribute("FORM_TOKEN_KEY");System.out.println("Token:" + saved);if(saved == null) {return false;}String token = request.getParameter("FORM_TOKEN_KEY");System.out.println("Token+token:" + token);if(token == null) {return false;}System.out.println("equals:" + saved.equals(token));return saved.equals(token);}/** * 清除存储在当前用户session中的表单标识号 */public synchronized void resetToken(HttpServletRequest request) {HttpSession session = request.getSession(false);if(session == null) {return;}session.removeAttribute(FORM_TOKEN_KEY);}/** * 产生表单标识号,并将保存到当前用户的session中 */public synchronized void saveToken(HttpServletRequest request) {HttpSession session = request.getSession();try {byte[] id = session.getId().getBytes();long current = System.currentTimeMillis();if(current == previous) {current++;} previous = current;byte[] now = String.valueOf(current).getBytes();//获得随机数摘要(128个字节)MessageDigest md = MessageDigest.getInstance("MD5");md.update(id);md.update(now);//base64编码BASE64Encoder encoder = new BASE64Encoder();String token = encoder.encode(md.digest());session.setAttribute(FORM_TOKEN_KEY, token);System.out.println("java:" + session.getAttribute("FORM_TOKEN_KEY"));} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}}
这样就完成了。
- 客户端和服务器后退操作防止表单重复提交
- 如何防止用户后退重复提交表单?
- 防止用户后退重复提交表单
- 如何防止用户后退重复提交表单
- java防止表单重复提交后退等
- jsp中防止刷新后退等操作造成表单重复提交(纯jsp或者struts)
- JAVAWeb_利用Session防止表单重复提交:10-客户端防表单重复提交和服务器端session防表单重复提交
- JAVAWeb_利用Session防止表单重复提交:10-客户端防表单重复提交和服务器端session防表单重复提交
- 防止刷新或后退页面重复提交表单
- 防止表单的重复提交(客户端)
- 客户端、服务器端防止表单重复提交
- 客户端服务端防止用户重复提交表单
- ASP轻松地实现了防止用户刷新多次提交表单和使用后退钮重复多次提交表单
- JavaWeb防止重复提交,重复刷新和后退
- struts2 防止后退重复提交
- java 后退防止重复提交
- 防止表单重复提交
- 防止重复提交表单
- (转)一些软件设计的原则
- 为程序员量身定制的12个目标
- java反射
- [uva] 10136 Chocolate Chip Cookies
- 路上看水
- 客户端和服务器后退操作防止表单重复提交
- 如何修改Struts2 FiledError样式
- 程序运行时间
- 阿里面试总结
- CMake编译OGRE source code时Boost的一些问题解决方法
- Android调用WebService
- IE smartdraw 等软件打开时Visual Studio 实时调试器的关闭方法
- 伤别
- 彻底抵制日货也许你可以做到