PS:實際使用中發現,第①種方法在火狐瀏覽中有時候有問題。第2種方法,在各個瀏覽器中都沒問題javascript
近作項目遇到了這樣的狀況:java
公司網絡比日常慢了很多,在點擊保存按鈕提交頁面後需等待挺長的一段時間,忍不住手賤點多了幾回,當提交完成後發現數據庫竟多出了幾條相同的數據!也就是說相同的內容提交了屢次。數據庫
經測試,當網絡很順暢的時,快速接二連三點擊提交按鈕,也會形成頁面重複提交!點擊多少次就會提交多少次,也就會錄入多少條數據!瀏覽器
固然,若錄入的數據中有惟一值的判斷處理或者數據表字段有惟一性約束,就不會出現錄入重複數據的狀況!服務器
在網上找了一下,找到了兩個經驗證可行的方法。網絡
第①種:異步
aspx頁面按鈕:函數
<asp:Button ID="btnSumbit" runat="server" Text="提交" onclick="btnSumbit_Click" />post
Page_Load 事件:測試
btnSumbit.Attributes.Add("onclick", "this.disabled=true;" +this.ClientScript.GetPostBackEventReference(btnSumbit, ""));
//若使用了 ASP.NET驗證控件 則要保證客戶端驗證函數 Page_ClientValidate() 的執行,代碼以下
//Page_ClientValidate() 函數用於在包含微軟驗證控件的aspx頁面中(客戶端js腳本),根據用戶輸入操做是否合法,返回True或者False
btnSumbit.Attributes.Add("onclick", "if (typeof(Page_ClientValidate) == 'function') { if (Page_ClientValidate() == false) { return false; }};this.disabled=true;" +this.ClientScript.GetPostBackEventReference(btnSumbit, ""));
提交按鈕 btnSumbit 對應的客戶端Html代碼以下:
<input type="submit" name="btnSumbit" value="提交" onclick="this.disabled=true;__doPostBack('btnSumbit','');" />
或
<input type="submit" name="btnSumbit" value="提交" onclick="if (typeof(Page_ClientValidate) == 'function') { if (Page_ClientValidate() == false) { return false; }};this.disabled=true;__doPostBack('btnSumbit','');" />
解析:
this.ClientScript.GetPostBackEventReference(btnSumbit, "")的做用就是在客戶端頁面生成調用 js 方法 __doPostBack(eventTarget, eventArgument) 的腳本,提交表單
客戶端js 方法__doPostBack(eventTarget, eventArgument)(ASP.NET頁面Render時自動生成) 以下(深刻理解__doPostBack):
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
第②種:
aspx頁面按鈕:
<asp:Button ID="btnSumbit" runat="server" Text="提交" UseSubmitBehavior="false" OnClientClick="this.value='正在提交';this.disabled=true;" onclick="btnSumbit_Click" />
//若使用了 ASP.NET驗證控件 則要保證客戶端驗證函數 Page_ClientValidate() 的執行,代碼以下
//Page_ClientValidate() 函數用於在包含微軟驗證控件的aspx頁面中(客戶端js腳本),根據用戶輸入操做是否合法,返回True或者False
<asp:Button ID="btnSumbit" runat="server" Text="提交" UseSubmitBehavior="false" OnClientClick="if (typeof(Page_ClientValidate) == 'function') { if (Page_ClientValidate() == false) { return false; }};this.value='正在提交';this.disabled=true;" onclick="btnSumbit_Click" />
後臺不用爲該Button添加什麼代碼
提交按鈕 btnSumbit 對應的客戶端Html代碼以下:
<span style="font-size:14px;color:#3366ff;"><input type="button" name="btnSumbit" value="提交" onclick="this.value='正在提交';this.disabled=true;__doPostBack('btnSumbit','');" />
或
<input type="button" name="btnSumbit" value="提交" onclick="if (typeof(Page_ClientValidate) == 'function') { if (Page_ClientValidate() == false) { return false; }};this.value='正在提交';this.disabled=true;__doPostBack('btnSumbit','');" /></span>
與方法①比較可知,提交按鈕在客戶端生成的Html代碼幾乎是同樣的,雖然 type 不一樣,但都是使用客戶端方法 __doPostBack('btnSumbit','') 提交表單
UserSubmitBehavior = true 按鈕控件和(<asp:Button/>和<asp:ImageButton/>)使用瀏覽器的提交功能,默認值
UserSubmitBehavior = false 按鈕控件(同上) ASP.NET 的 postback 提交機制,此時 ASP.NET 會添加一段客戶端腳原本回傳該表單,也就是 __doPostBack(eventTarget, eventArgument) 方法
(注意:ASP.NET 服務器控件除了<asp:Button/>和<asp:ImageButton/> 其它的全部可回發控件都是經過 __doPostBack 方法觸發頁面的 PostBack 提交)
=========================================================================================
除了上面兩種方法,本身還摸索出了一個簡單可用方法,也可防止屢次點擊重複提交:
定義一個 js 全局變量 var IsClick=false 是否已點擊提交,true:已點擊提交;false:未點擊
<asp:Button ID="btnSumbit" runat="server" Text="提交" OnClientClick="if (IsClick==false) { IsClick=true; return true;} else { return false;}" onclick="btnSumbit_Click" />
//若使用了 ASP.NET驗證控件 則要保證客戶端驗證函數 Page_ClientValidate() 的執行,代碼以下
//Page_ClientValidate() 函數用於在包含微軟驗證控件的aspx頁面中(客戶端js腳本),根據用戶輸入操做是否合法,返回True或者False
<asp:Button ID="btnSumbit" runat="server" Text="提交" OnClientClick="if (typeof(Page_ClientValidate) == 'function') { if (Page_ClientValidate() == false) { return false; }};if (IsClick==false) { IsClick=true; return true;} else { return false;}" onclick="btnSumbit_Click" />
(注意:若是頁面說用了UpdatePanel 且<asp:Button/> 包含在 UpdatePanel 裏面,在異步回發以後(頁面局部刷新以後)必須將 IsClick 的值重置爲 false,可用以下方法:
$(document).ready(function () {
//endRequest 事件 :在異步回發完成,而且控制權返回到瀏覽器以後引起
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
});
//updatepanel 異步回發局部刷新後處理函數
function EndRequestHandler(sender, args) {
IsClick = false;
}
)