两种解决表单重复提交的方式PRG和Token

来源:互联网 发布:51单片机流水灯原理图 编辑:程序博客网 时间:2024/06/05 07:48

引言:在系统开发过程中,如何避免表单重复提交一直是一个令人头疼的问题,好在前辈们都已经开发了数种解决方式,这次博主将会介绍两种解决表单重复提交的问题。

  • 我们知道,在JSP&Servlet中有两种跳转方式,一种是重定向跳转,特点是:
  • 重定向跳转使用URL重写(?+键值对)的方式进行值的传递,值显示在浏览器的地址栏中
  • 重定向传值方式适合不敏感数据及简单的字符串、数字等基本类型
  • 重定向跳转后浏览器的地址栏中显示的是跳转目标的URL(地址栏会发生改变)
  • 重定向跳转不会引起表单重复提交
  • 二是请求转发跳转,特点是:
  • 请求转发使用HttpServletRequest对象的setAttribute方法进行值传递,值不会显示在地址栏中
  • 请求转发跳转会引起表单的重复提交
  • 请求转发跳转后地址栏不会显示跳转目标的URL(地址栏不会发生改变)
  • 请求转发跳转值方式适合传递敏感数据及对象,数组,集合等类型的数据

从上面我们可以清楚的看到两者的一些区别,虽然在开发过程中,请求转发跳转较重定向跳转有很大的优势,比如,可以传递列表,或者数据,对象及敏感数据,且URL不会改变,用户信息不会被URL所泄露等等,但是请求转发方式则有一个致命的弱点,那就是:可能引起表单重复提交问题

  1. 下面就介绍如何利用PRG来解决这个问题,所谓PRG,其实就是Post,Redirect,Get。
    如下图所示,表单数据经过Post方式提交至insert order的服务器,如果此时用户刷新界面,势必造成表单重复提交,但是新建一个页面和服务器以后,我们就可以在提交之后,将路径进行重定向(修改了URL路径)为新建的页面和Servlet容器,此容器中有一个doGet()方法,然后再在用户端界面进行展示,此时所处的页面就是新重定向后的页面,再次刷新之后就不会再有表单重复提交的问题了。

这里写图片描述

当然,PRG不是万能的,以下几种情况PRG也是不能解决的:
比如:

  • 由于服务器响应缓慢,用户刷新提交POST请求造成的重复提交。

  • 用户点击后退按钮,返回到数据提交界面,导致的数据重复提交。

  • 用户多次点击提交按钮,导致的数据重复提交。

  • 用户恶意避开客户端预防多次提交手段,进行重复数据提交。

2.第二种解决方法是使用Token的方式
token令牌机制示意图
1. 接收客户请求(执行doGet()方法),产生Token,并放入session和request中
2. 在表单中接收Token
3. 提交表单到doPost()方法中
4. 处理表单请求前验证Token是否和Session中的一致,如果一致则不是重复提交,删除Session中Token,如果不一致则提示提交失败
自我理解:首先doget方法产生一个永不重复的token值,然后将token放入session和req中,第一次请求时,session中是有值的,校验正确以后,删除session中的值,然后第二次提交的时候,session中已经没有值了,所以匹配不会成功,也就是表示表单重复提交了,或者是session时间久过期了。