防止表单重复提交

一个业务真实场景:在执行表单保存的时候,由于网络延迟等原因,点击保存按钮直接刷新页面,浏览器会重复提交表单信息导致数据库插入两条数据,这种情况控制保存按钮不能解决,设置主键约束太过暴力,我们可以利用session防止表单重复提交。

1.表单重复提交可能性原因

​ 1、由于用户误操作,多次点击表单提交按钮。

​ 2、由于网速等原因造成页面卡顿,用户重复刷新提交页面。

​ 3、黑客或恶意用户重复恶意提交表单(攻击网站)。

2.利用session防止表单重复提交

​ 1、获取用户填写用户名和密码的页面时向后台发送一次请求,这时后台会生成唯一的随机标识号,专业术语称为Token(令牌)。

2、将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端。

3、服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号

3.代码范例(java+jsp)

  1. 在controlle层生成Token(令牌)和跳转到jsp页面
@RequestMapping("/")
	public ModelAndView get(HttpServletRequest request){
        String token =  UUID.randomUUID().toString() ;//创建令牌
		request.getSession().setAttribute("token", token);  //在服务器使用session保存token(令牌)
        String url = "跳转的页面";
        return new ModelAndView(url, "");
    }

        
  1. 在jsp页面中使用隐藏域来存储Token(令牌),随着表单保存时候提交到后台。
">
  1. 在表单提交的controller中判断是否是重复提交
@RequestMapping("/save")
public ModelAndView save(){
    if(!repeatResult){//不是重复提交,调用保存接口并删除session
			//调用service业务处理层接口
			request.getSession().removeAttribute("token");//移除session中的token
		}
}
/**
     * 判断客户端提交上来的令牌和服务器端生成的令牌是否一致
     * @param request
     * @return
     *         true 用户重复提交了表单
     *         false 用户没有重复提交表单
     */
    public static boolean isRepeatSubmit(HttpServletRequest request) {
        String client_token = request.getParameter("token");
        //1、如果用户提交的表单数据中没有token,则用户是重复提交了表单
        if(client_token==null){
            return true;
        }
        //取出存储在Session中的token
        String server_token = (String) request.getSession().getAttribute("token");
        //2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
        if(server_token==null){
            return true;
        }
        //3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
        if(!client_token.equals(server_token)){
            return true;
        }
        return false;
    }

你可能感兴趣的:(spring)