在網速慢或者網站反應慢的情況下,如果提交表單需要超過5秒的時間還未提交成功,多數人會重新點擊提交。這樣不僅造成錯誤的數據,還會加劇服務器的壓力。
通過使用HttpModule,我們可以在表單處理前,檢測一些標志,從而防止用戶重復提交數據,再通過一些接口,讓用戶自己來處理重復提交時,應該如何告訴用戶。
通過使用HttpModule,我們也可以在客戶端表單提交時,使用DIV覆蓋住表單,從UI層防止用戶再次單擊提交(用戶直接F5管不了)。
這種方法使用簡單,直接把腳本和圖片放在指定的目錄中,然後在Web.config中添加Module
<httpModules>
<!--防止重復提交 LOG記錄MODULE -->
<add name="NonReduplicatePostModule" type="tests.NonReduplicatePostModule,test"/>
</httpModules>
下面是實現代碼:
/// NonReduplicatePostModule 的摘要說明。
/// </summary>
public class NonReduplicatePostModule : System.Web.IHttpModule
{
private static ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private const string hiddenFileName = "__NonReduplicatePostModule__";
private const string maskdivScriptRelativeUrl = "~/js/maskDiv.js";
private const string onformSubmit = "Evlon.MaskDiv.Instance.show();";
private HttpApplication context = null;
#region IHttpModule 成員
public void Init(HttpApplication context)
{
this.context = context;
this.context.PreRequestHandlerExecute+=new EventHandler(context_PreRequestHandlerExecute);
}
public void Dispose()
{
this.context.PreRequestHandlerExecute-=new EventHandler(context_PreRequestHandlerExecute);
}
#endregion
private void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication webApp = sender as HttpApplication;
if(webApp != null)
{
//已經處理過,提示用戶不要重復提交
Page page = webApp.Context.Handler as Page;
if(page != null)
{
page.PreRender+=new EventHandler(page_PreRender);
//找到Page,添加時間
if(webApp.Request.Form[hiddenFileName] != null)
{
string flag = webApp.Request.Form[hiddenFileName].ToString();
if(webApp.Context.Cache.Get(flag) != null)
{
log.Debug("found reduplicate post");
if(page is IReduplicatePostHandler)
{
webApp.Context.Handler = new ReduplicatePostHandler((IReduplicatePostHandler)page);
}
else
{
webApp.Context.Handler = new ReduplicatePostHandler();
}
}
else
{
//放進緩存中,表示已經被處理過,在一分鐘後自動移聊(可再次提交)
webApp.Context.Cache.Add(flag,DateTime.Now,null,System.Web.Caching.Cache.NoAbsoluteExpiration,TimeSpan.FromMinutes(1),System.Web.Caching.CacheItemPriority.Normal,null);
}
}
}
}
}