防止表单重复提交

很多的web应用程序中我们必须要对表单的重复提交做出处理。我们可以使用以下几种方式来防止用户重复提交。

1、使用JavaScript 

2、使用Token(令牌)验证提交信息 

3、使用session记录上次提交时间

1. 使用JavaScript

有这样的一种情况,用户提交请求之后,页面还没有来得及刷新,或者响应的事件比较长,

那么用户就有可能再次点击提交按钮提交请求。我们可以在页面中定义一个全局的javaScript变量,

存储true和false,true表示已经提交,false表示没有提交,当用户点击了提交之后,首先检查变量的值,

如果为true,则提示用户表单已经提交,如果是false,则将表单提交,然后将变量的值变为true。

这样用户再次点击提交,变量就成true了,此时就提醒用户表单已经提交。还有一种方式就是如果

表单已经提交,则通过javaScript把表单的按钮禁用。将按钮标记的disabled值设置为”disabled”,

这样用户就不能点击按钮提交了。这两种方法由于都是在客户端做出的限制,所以不是很安全,

恶意用户可以通过禁用javaScript代码。还有如果用户使用的不是按钮,

而是通过链接来提交数据的,这种方式就防止不了了。

2、使用Token验证的方式

思路:在程序生成带表的单页面之前,先在服务端生成一个唯一的Token,(一个唯一的字符串)然后放到session中,

生成页面的时候,从session中取出这个标识号,放到隐藏域中,或者附加到url后面,

将来提交的时候将这个标识号一起提交。服务器收到这个提交的数据之后与session中存放的数据对比,

如果一致,则处理请求,然后清除掉session中存放的值(废弃Token).如果不一致,提示重复提交。

我们可以使用UUID作为生成的唯一的Token的值,UUID就是(Universally Unique Identifier,通用唯一识别码)。

JDK中提供了java.util.UUID类可以生成这种码值,只需要调用UUID.randomUUID() 即可

3、防止用户频繁发出请求

如果用户频繁发出请求,那么就会给服务器造成很大的压力。思路:我们可以在session中记录用户上次请求的时间,

每次请求的时候从session中取出上次请求的时间(时间可以使用System.currenttimeMillis()来获取系统当前时间)

与当前时间进行对比,如果间隔时间太短,则提示给用户。下面给个Struts2框架使用标签防止表单重复提交。

Struts框架就使用了Token的方式来防止表单重复提交。首先需要搭建好Struts2框架所需环境,


<s:token />标签防止重复提交,用法如下:第一步:在表单中加入<s:token />

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>Index</title>
  </head>
  
  <body>
    <s:form action="jason" namespace="/test" method="post"> 
    	Name:<s:textfield name="name"/><s:token/>
    	<input type="submit" value"Submit">
    </s:form>
  </body>
</html>


第二步:加入了“token”拦截器和“invalid.token”返回结果。因为“token”拦截器在会话的token与请求的token 不一致时,

将会直接返回“invalid.token”结果。服务器端的token是每次请求都会变化,而客户端token是不变的。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC 
	"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
	"http://struts.apache.org/dtds/struts-2.0.dtd" >
<struts>
	<!--	开发模式-->
	<constant name="struts.devMode" value="true"/>
	<constant name="struts.ui.theme" value="simple"/>
	
	<package name="com.jason" namespace="/test" extends="struts-default">
		<action name="jason" class="com.jason.web.action.BuyerAction">
			<!--	struts拦截器-->
			<interceptor-ref name="defaultStack"/>
			<!--	token拦截器-->
			<interceptor-ref name="token"/>
			<!--	配置二次请求后跳转的页面-->
			<result name="invalid.token">/index.jsp</result>
			<result>/WEB-INF/page/message.jsp</result>
		</action>
	</package>
</struts>

BuyerAction.java

package com.jason.web.action;

public class BuyerAction {
	
	private String name;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String execute() throws Exception{
		return "success";
	}
}

message.jsp页面里显示出时间,如果不适用token当我们每次刷新页面,都会访问Action中的方法,时间在变化。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Index</title>
  </head>
  
  <body>
    <s:property value="name"/><br/>
    <%=new Date() %>
  </body>
</html>

当我们第一次请求后,再次请求页面会返回到index.jsp首页。

原文地址:https://www.cnblogs.com/jasontec/p/9601727.html