Web項目上線后當訪問壓力增大時,處理速度往往比在測試環境時慢好多倍。當用戶點擊頁面控件提交請求半天沒反應時,他就會不停的重復點擊該控件,造成請求的重復提交,這個時候很多問題就暴露出來了。上個項目是用Asp.net+C#開發的,為了避免這個重復提交問題,在以前的一個js版本上做了一些完善,雖然技術比較傳統,但還是能做為應急之用。
Asp.net客戶端提交的路徑分為以下幾種:
- a) 點button提交 -> form的onsubmit事件
b) 點button提交 -> button的WebForm_DoPostBackWithOptions ->form的WebForm_OnSubmit(包含了自定義的submit事件) - c) 點button -> __doPostBack -> 運行form的onsubmit –> submit
d) 點button -> WebForm_DoPostBackWithOptions -> __doPostBack -> 運行form的onsubmit(WebForm_OnSubmit) –> submit
該js的代碼如下:
Code//--------------------------------------------------------- // 作者:野文(Jasson) http://qguohog.cnblogs.com // 日期:2010-12-18 // 功能:避免重復提交數據。若某個按鈕控件不需要啟用重復提交, // 則在其上添加屬性AvoidRepeatSubmit="false" //--------------------------------------------------------- $(document).ready( function() { var isPosting = false; var divMask = null; var divTipContent = null; var formOnSubEvts = new Object(); var submitByClickCtrl = null; function _doPostBack() { }; if (typeof (__doPostBack) == "function") { _doPostBack = __doPostBack; __doPostBack = _doPostBackNew; } function _doPostBackNew(sender, args) { try { submitByClickCtrl = $("#" + sender); } catch (e) { try { submitByClickCtrl = $("#" + sender.replace('$', '_')); } catch (ex) { submitByClickCtrl = null; } } _doPostBack(sender, args); } function createLayerMask() { if (divMask == null) { divMask = $("<div tabindex='0'></div>"); $(divMask).addClass("arsMask"); $(document.body).append(divMask); bindEvents(divMask); } } function createTipContent() { if (divTipContent == null) { divTipContent = $("<div></div>"); $(divTipContent).addClass("arsTipContent"); $(document.body).append(divTipContent); bindEvents(divTipContent); } } function bindEvents(divObj) { $(divObj).blur(function() { this.focus(); }); $(divObj).bind("drag", function() { return false; }); $(divObj).bind("selectstart", function() { return false; }); $(divObj).bind("contextmenu", function() { return false; }); $(divObj).bind("focus", function() { this.blur(); }); } function setLocation() { $(divMask).height(document.documentElement.scrollTop + document.documentElement.clientHeight); $(divMask).width(document.documentElement.scrollLeft + document.documentElement.clientWidth); $(divTipContent).css("left", document.documentElement.scrollLeft + (document.documentElement.clientWidth - $(divTipContent).width()) / 2); $(divTipContent).css("top", document.documentElement.scrollTop + (document.documentElement.clientHeight - $(divTipContent).height()) / 2); } function showMaskAndTipContent(isShow) { isPosting = isShow; createLayerMask(); createTipContent(); if (isShow) { setProgressInfo(); $(divMask).show(); $(divTipContent).show(); setLocation(); $(window).bind("scroll", setLocation); $(window).bind("resize", setLocation); } else { $(divMask).hide(); $(divTipContent).hide(); $(window).unbind("scroll", setLocation); $(window).unbind("resize", setLocation); } } function setProgressInfo(text, width, height) { if (divTipContent != null) { proText = text || "處理中,請稍候..."; proWidth = width || 140; proHeight = height || 40; $(divTipContent).html(proText); $(divTipContent).width(proWidth); $(divTipContent).height(proHeight); } } function useAvoidRepeatSubmit(ctl) { var avoid = $(ctl).attr("AvoidRepeatSubmit"); return (typeof (avoid) == "undefined" || avoid.toLowerCase() != "false"); } $("input[type=submit],input[type=image]").click( function() { submitByClickCtrl = this; } ); $("form").each( function() { var eSubmit = this.onsubmit; if (typeof (this.onsubmit) == "function") { formOnSubEvts[$(this).attr("name")] = eSubmit; this.onsubmit = null; } this.onsubmit = function(e) { var evt = e || window.event; if (isPosting && evt != null) { return evt.returnValue = !(evt.cancelBubble = true); } var eSubmit = formOnSubEvts[$(this).attr("name")]; if (typeof (eSubmit) == "function" && !eSubmit()) { return false; } if (submitByClickCtrl != null) { if (useAvoidRepeatSubmit(submitByClickCtrl)) { showMaskAndTipContent(true); } } return true; } } ); } );
效果如下:
示例Demo代碼下載:AvoidRepeatSubmit.