網頁重覆送出問題,IE的專利?
同事負責的系統接到抱怨,資料庫被塞入重覆資料,經過一番追查後,發現是使用者的非常態操作所導致,簡單來說--就是送出鈕連按兩下啦!
程式人員或受過訓練的操作員都已經很習慣"執行動作後等待回應"的過程,在按下送出鈕後,就會靜候程式的回應,不會急躁地狂按送出鈕。不過,在實際世界中,並不是每個使用者都會乖乖依你的預期進行操作(所以我們才需要猴子來幫忙測試),遇到缺乏耐性、搞不清狀況或暴怒的使用者,事情的發展就很難預料。
我一直有個錯誤的印象,使用者在按下送出鈕後,瀏覽器就會結束目前的網頁操作,顯示空白等待Postback的結果傳回(其實我已經被狂電過一次,但顯然還是沒學起來)。事實上,在Postback後,瀏覽器會停留在原網頁上,一直到新網頁內容送達為止,在此之前,網頁仍然可以被操作,這給了使用者重覆按下送出鈕的機會。
不信? 我用了以下的ASP.NET網頁來驗證。
<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
protected void btnSend_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(10000);
using (StreamWriter sw =
new StreamWriter("A:\\Output.txt", true))
{
sw.WriteLine("{0:yyyy-MM-dd HH:mm:ss.fff} {1}",
DateTime.Now, txtData.Text);
sw.Close();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Submit Twice</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtData" runat="server"></asp:TextBox>
<asp:Button ID="btnSend" runat="server" Text="Send"
onclick="btnSend_Click" />
</div>
</form>
</body>
</html>
在以上的測試中,程式會Delay 10秒才將結果寫入output.txt並傳回結果,在這等待的10秒內使用者有機會從容地多按幾次Send鈕。大約10秒後,output.txt中就會連續冒出多筆記錄,記錄的時間間隔在10秒內,證明了是網頁內容送抵前多按幾次送出鈕就會重覆送出多次Postback。
去網路上爬了一下文,發現大部分建議的解決方式都是用Javascript在按鈕的onclick事件中將按鈕設成disabled防止重覆按下,甚至有人特別寫了只能按一次的送出鈕。
但在我的認知中,這件事本當由瀏覽器處理,而不是靠網頁設計師在每一顆送出鈕上加工;就Postback的行為而論,按下後網頁存在的正當性就消失了,只是看守性質,除了默默等待新網頁內容進行輪替外,什麼都不應該做,更別說每按一次送出就Postback一次。
我原本以為這是網站開發者的宿命,是瀏覽器天性使然,心念一轉,改用Firefox測試一下,卻驚奇地發現,Firefox在等待的10秒內,Send鈕可以重覆被按下,卻不會重覆送出POST Request,這才是我期望的Behavior!! 再追加測試了IE8,發現跟IE7一樣會有重覆送出的行為,有點失望。
綜合了以上的研究,我覺得這是個不合理的行為設計(就跟之前IE6中的下拉選單會浮在任何元素最上層一樣),剛才透過Microsoft Connect提了建議,如果有接到回應,再跟大家報告吧!