|
admin
- 管理员
- 2580
- 767
-
2009-03-17
|
admin
2009-05-21 23:01
| 只看楼主
树型|
收藏|
小
中
大
1
#
使用HttpModule来禁用Web表单重复提交
在网速慢或者网站反应慢的情况下,如果提交表单需要超过5秒的时间还未提交成功,多数人会重新点击提交。这样不仅造成错误的数据,还会加剧服务器的压力。 通过使用HttpModule,我们可以在表单处理前,检测一些标志,从而防止用户重复提交数据,再通过一些接口,让用户自己来处理重复提交时,应该如何告诉用户。 通过使用HttpModule,我们也可以在客户端表单提交时,使用DIV覆盖住表单,从UI层防止用户再次单击提交(用户直接F5管不了)。 这种方法使用简单,直接把脚本和图片放在指定的目录中,然后在Web.config中添加Module Code <httpModules> <!--防止重复提交 LOG记录MODULE --> <add name="NonReduplicatePostModule" type="tests.NonReduplicatePostModule,test"/> </httpModules>
下面是实现代码: Code /// NonReduplicatePostModule 的摘要说明。 ///</summary> publicclass NonReduplicatePostModule : System.Web.IHttpModule { privatestatic ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); privateconststring hiddenFileName ="__NonReduplicatePostModule__"; privateconststring maskdivScriptRelativeUrl ="~/js/maskDiv.js"; privateconststring onformSubmit ="Evlon.MaskDiv.Instance.show();"; private HttpApplication context =null;
#region IHttpModule 成员
publicvoid Init(HttpApplication context) { this.context = context; this.context.PreRequestHandlerExecute+=new EventHandler(context_PreRequestHandlerExecute); }
publicvoid Dispose() { this.context.PreRequestHandlerExecute-=new EventHandler(context_PreRequestHandlerExecute); }
#endregion
privatevoid 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); } } } }
}
privatevoid page_PreRender(object sender, EventArgs e) { Page page = sender as Page; if(page !=null) { //找到Page,添加时间 page.RegisterHiddenField(hiddenFileName,string.Format("{0}_{1}_{2}",page.Session.SessionID.GetHashCode(), page.GetType().GetHashCode(), DateTime.Now.Ticks)); //表单UI显示 MASKDIV page.RegisterClientScriptBlock("maskdiv_include","<script type='text/javascript' src='"+ page.ResolveUrl(maskdivScriptRelativeUrl) +"' ></script>"); page.RegisterOnSubmitStatement("maskdiv", onformSubmit); }
} }
publicinterface IReduplicatePostHandler { void OnReduplicatePost(HttpContext context, EventArgs e); }
internalclass ReduplicatePostHandler : IHttpHandler { private IReduplicatePostHandler handler =null; internal ReduplicatePostHandler(IReduplicatePostHandler handler) { this.handler = handler; }
internal ReduplicatePostHandler() { }
#region IHttpHandler 成员
publicvoid ProcessRequest(HttpContext context) { if(handler !=null) { handler.OnReduplicatePost(context,new EventArgs()); } else { context.Response.Write("不要重复提交"); } }
publicbool IsReusable { get { // TODO: 添加 ReduplicatePostHandler.IsReusable getter 实现 returnfalse; } }
#endregion
}
用到的JS文件:/js/MaskDIV.js Code Evlon = {}; Evlon.MaskDiv =function() { var div = window.document.createElement("DIV"); div.style.position ="absolute"; div.style.top ="0px"; div.style.left ="0px"; div.style.width ='100%';//document.body.scrollWidth + 'px'; div.style.height ='100%'; //document.body.scrollHeight + 'px'; div.style.backgroundColor ="white"; div.style.zIndex =999; div.style.filter ="Alpha(style=0,opacity=50)"; div.style.opacity="0.50"; this.divMask = div; div = window.document.createElement("DIV"); div.style.position ="absolute"; div.style.top ="0px"; div.style.left ="0px"; div.style.width ='100%';//document.body.scrollWidth + 'px'; div.style.height ='100%'; //document.body.scrollHeight + 'px'; div.style.zIndex =1000; this.divTooltip = div;
this.show =function() { //创建半透明DIV window.__maskDiv__ = document.body.insertAdjacentElement('afterBegin',this.divMask); //创建提示DIV window.__maskDivText__ = document.body.insertAdjacentElement('afterBegin',this.divTooltip); window.__maskDivText__.innerHTML ="<table style='border-collapse:collapse;border-width:0px;width:100%;height:100%;'0><tr height='38%'><td></td></tr><tr><td align='center' valign='top'>"+ "<table style='border-collapse:collapse;border:solid 1px yellow;'><tr><td align='right'><img width='20' height='20' src='image/loading.gif' usesrc='image/loading.gif' onerror='this.src= this.usesrc = \"../\" + this.usesrc'/></td>" + "<td align='left'><span style = 'filter:alpha(opacity=100);background-color:#ccc;font-size:20px'>提交中 .</span></td></tr></table>"+ "</td></tr></table>";
} this.hide =function() { if(window.__maskDiv__ !=null) { document.body.removeChild(window.__maskDiv__); window.__maskDiv__ =null; } if(window.__maskDivText__ !=null) { window.__maskDivText__.innerHTML =''; document.body.removeChild(window.__maskDivText__); window.__maskDivText__ =null; } } }
Evlon.MaskDiv.Instance =new Evlon.MaskDiv();
window.showModalDialogMask =function(sURL , vArguments, sFeatures) { var sign = window.showModalDialog(sURL , vArguments, sFeatures); if(sign !=""&& sign !=null) { //创建半透明DIV Evlon.MaskDiv.Instance.show(); } returnnull; //return sign; }
|