WebForm中如何防止页面刷新,后退导致的重复提交

当用户按下浏览器中的 F5 键刷新当前页面时,对这一过程进行检测所需的操作步骤。页面刷新是浏览器对特定用户操作(按 F5 键或单击“刷新”工具栏按钮)的响应。页面刷新操作是浏览器内部的一种操作,因为浏览器不会为事件或回调发出任何外部通知。从技术上讲,页面刷新是通过 “简单”重复最新请求来实现的。换句话说,浏览器将缓存已处理的最新请求,并在用户单击页面刷新键时重新发布已处理的请求。

正 是因为所有浏览器(据我所知)不会为页面刷新事件提供任何类型的通知,所以服务器端的代码(例如,ASP.NET、典型 ASP 或 ISAPI DLL)根本无法区分刷新请求与一般的提交或回发请求。这样,就会导致WebForm页面中form中的内容被重复提交.那么如何防止这种重复提交呢,一般从客户端和服务器端考虑

1,客户端: btn submit之后禁用所有提交按钮或控件, 也可以加一个透明的遮罩层把页面元素挡住。

2. 服务器端  转载自 http://www.cnblogs.com/Freeway/p/detecting-browser-refresh-from-code-behind-in-asp-dotnet.html

浏览器的"刷新"常会导致问题, 特别是当页面和数据库有交互的时候, 结果可能更糟. 因为, 每次页面刷新, 如果没有经过代码处理, 就会重复做一次数据库操作.

这就可能导致数据的不一致, 甚至程序挂掉.

检测"刷新"的一种方法就是用JavaScript禁用掉F5和右击事件. 但就算这么做了, 终端用户还是有N种其它方法来刷新页面的, 比如, Ctrl+R.

最好的防止"刷新"是代码被重复调用的方法还是在服务器端做检查, 并经行处理.

下面的代码放在page_load方法中, 它可以检测"刷新":

bool IsPageRefresh = false;
//this section of code checks if the page postback is due to genuine submit by user or by pressing "refresh"
if (!IsPostBack)
{
    ViewState["ViewStateId"] = System.Guid.NewGuid().ToString();
    Session["SessionId"] = ViewState["ViewStateId"].ToString();
}
else
{
    if (ViewState["ViewStateId"].ToString() != Session["SessionId"].ToString())
    {
        IsPageRefresh = true;
    }
    Session["SessionId"] = System.Guid.NewGuid().ToString();
    ViewState["ViewStateId"] = Session["SessionId"].ToString();
}   

之后, 就可以在后台代码中用"IsPageRefresh"来判断一个PostBack是来自用户点击按钮还是浏览器的"刷新"啦.

如果在一次submit之后用F5刷新页面,会导致页面再次提交。这次提交和上一次完全相同,甚至包括viewstate的状态…结果就是button_Click事件的逻辑会被重复执行,导致不期望的结果。而存储在session中的值并不受F5刷新的影响而会用新的值,所以可以用它和viewstate比较来判断是否F5刷新。

 

posted on 2016-10-12 13:36  新西兰程序员  阅读(1129)  评论(0编辑  收藏  举报