我有一個表單。在提交一個按鈕時,它會在db中插入一條記錄。如果我回到瀏覽器並刷新頁面,它會重新提交,導致各種各樣的問題。我如何確保用戶無法刷新上一頁,並且該頁面的狀態在執行另一次自動提交時會如此刷新?防止重新提交瀏覽器刷新數據
-
我沒有使用ViewState的
- 。我其實有它在頁面指令
- 沒有,Response.Redirect的不解決這個問題,禁用。用戶仍然可以回到瀏覽器的後退按鈕並刷新它們提交的點,它仍然會運行按鈕的事件,將數據下游發送到我的DL插入
我有一個表單。在提交一個按鈕時,它會在db中插入一條記錄。如果我回到瀏覽器並刷新頁面,它會重新提交,導致各種各樣的問題。我如何確保用戶無法刷新上一頁,並且該頁面的狀態在執行另一次自動提交時會如此刷新?防止重新提交瀏覽器刷新數據
最簡單的方法是將表單在< asp:UpdatePanel>
。這樣,所有回傳都通過AJAX完成,瀏覽器永遠不會要求您重新提交表單。
謝謝,但我遠離MS AJAX控件。 – PositiveGuy 2009-11-10 01:45:30
是的,絕對是最簡單的! – 2012-02-16 03:56:55
這樣做的最好的兩種方法是:
在不同的領域執行檢查對數據庫
創建使用基於時間的鹽的形式隱藏記號。如果您在腳本中放入邏輯以檢查現有時間並將其與標記進行比較,則可以允許提交或定義它。例如,如果表單是在特定時間繪製的,則存儲該標記,並在30-60秒內提交,但在此之後您不能。
我最常使用的解決方案是這樣的:
當用戶第一次訪問該頁面(非回發),生成令牌值(GUID很容易)。獲取此令牌值並將其存儲在其會話變量和頁面中的隱藏字段中。作爲一個領域,這個價值應該堅持通過往返服務器沒有啓用ViewState(我可能會被誤算,所以請檢查它!)。如果頁面被刷新(並且表格值丟失),非回發初始化會生成一個新值。
當頁回,檢索隱藏字段值,並將其與用戶的會話變量的預期值:
示例代碼來實現這種解決方案:
public partial class MyPage : Page
{
protected HiddenField tokenField;
protected void Page_Load()
{
if(!IsPostBack)
CreateToken();
}
// Call this method to establish a token in session and on the page.
private void CreateToken()
{
string token = new Guid().ToString();
Session["dupeToken"] = token;
tokenField.Value = token;
}
// Call this method to validate the token before continuing workflow.
private bool TokenIsValid()
{
string expectedToken = (string)Session["dupeToken"];
if(expectedToken == null)
return false;
string actualToken = tokenField.Value;
return expectedToken == actualToken;
}
// Call this method when the page submission is complete to prevent re-submission.
private void ConsumeToken()
{
Session["dupeToken"] = null;
}
}
如果您點擊後退按鈕並「重放」提交,令牌將匹配:就像任何其他表單元素一樣,存儲原始令牌的隱藏字段也不會改變。 – 2009-11-10 17:57:24
他們不應該這樣做,因爲令牌只在訪問字段中不存在值的表單(即唯一提交)時纔會生成。由於令牌在提交的Session中被「消耗」,因此它不會出現在表單的重播中。 – 2009-11-11 08:57:18
問題是,「後退」按鈕:當您使用後退按鈕導航到您發佈的頁面時,其所有表單輸入元素(包括隱藏字段)都具有您用於原始發佈的值。因此,當用戶重新提交時,原始令牌仍然存在。 – 2009-11-11 21:41:01
如若第二次提交實際上是* *違法,還是僅僅是*通常爲*意想不到的? – 2009-11-10 01:44:40
許多人正在尋找這個問題的答案。我也列入該名單。問題是每一個國家「編程你的代碼,這樣可以避免」...像DB中的distint字段......但是有很多ifs和buts。截至目前,我仍在搜索... – 2009-11-10 06:25:47