在ASP.NET Web Form和MVC中防止F5刷新引起的重复提交

什么是刷新/重新载入

 

IE中的刷新(Refresh),在FF和Chrome中称为重新载入(Reload),与正常进入页面的区别在于以下两点:

1. 缓存控制

如果文件(比如图片)在本地缓存中已经存在,正常进入页面会不访问服务器而直接从本地加载。而对于刷新操作,即使存在本地缓存,也会强制访问服务器检查更新,在Request Header中会带有“If-Modified-Since”标签。如果文件没有更新,服务器会返回304, 否则返回200及更新后的文件。

2. 重复提交

刷新会重复提交上一次的请求。比方说新建一张订单然后保存,而系统操作成功后停留在当前页面。此时进行刷新,浏览器会弹出一个对话框询问是否继续,点确定后浏览器会重复提交上一次的POST请求(点击保存的请求),系统可能会产生一张重复的订单。当然,上次操作如果只是Get请求而非POST,重复提交并不会导致这种问题。

如何防止重复提交

防止重复提交的方法与PRG(POST-Redirect-GET)模式有一些相似之处,具体来说,当Web服务器识别到一个重复提交的POST请求的时候,重定向到当前页面,然后浏览器以GET的方式请求该页面。如果使用HttpWatch之类的工具查看网络请求,可以看到会有两个请求,302 & 200。

ResubmitInIE9

现在问题在于如何识别一个请求是由刷新引起的。我们利用刷新操作会重复提交上一次请求,而不是当前请求的特性,可以有以下方案:在服务器端(Session)和页面(可以是页面上一个hidden field)上都设置一个整型标志位,在每次POST请求中都比较两者的值,然后自增。在正常提交情况下,浏览器会提交当前页面上hidden field的值,所以每次该值与Session中的都相等;在刷新情况下,提交的值是上次请求的值,就会与Session的不相等,由此得知是刷新操作引起的重复提交。

这类似于Struts中的Token验证

在这里我们把页面hidden field称为Client Flag,具体的流程如下

ResubmitFlow

在最后一步刷新页面的时候,hidden field的值为3,但是浏览器会重复提交上一次的请求(2),造成与Session中的值(3)不一致。

在ASP.NET MVC中的实现

添加一个自定义的ActionFilter.

View Code
 public class NoResubmitAttribute : ActionFilterAttribute
    {
        private static readonly string HttpMehotdPost = "POST";
        private static readonly string prefix = "postFlag";
        private string nameWithRoute;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var controllerContext 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值