防止在浏览器刷新时重新提交数据

时间:2009-11-10 01:33:58

标签: asp.net

我有一张表格。在提交按钮时,它会将记录插入到数据库中。如果我回到我的浏览器并刷新页面,它会重新提交它,导致各种各样的问题,如你所能想象的那样。如何确保用户无法刷新上一页,并且该页面的状态会在刷新时自动提交另一个?

  1. 我没有使用ViewState。我实际上已在页面指令
  2. 中禁用它
  3. 不,Response.Redirect无法解决此问题。用户仍然可以使用浏览器的后退按钮返回并在他们提交的位置刷新,它仍将运行按钮的事件,将数据下游发送到我的DL插入

3 个答案:

答案 0 :(得分:3)

我经常使用的解决方案是:

当用户首次访问该页面(Non-PostBack)时,生成一个令牌值(GUID很容易)。获取此标记值并将其存储在其Session变量和页面中的隐藏字段中。作为一个字段,这个值应该在没有启用ViewState的情况下通过往返服务器来持续存在(我可能会误认为那个数量,所以请检查它!)。如果页面被刷新(表单值丢失),Non-PostBack初始化将生成一个新值。

回发页面时,检索隐藏字段值并将其与用户会话变量中的预期值进行比较:

  • 如果令牌匹配,请接受提交为“正版”,从会话变量中删除令牌,然后继续您的工作流程。
  • 如果会话变量中缺少令牌,则用户正在尝试再次提交表单。 - 如果令牌不匹配,则用户“重播”旧表单提交。

实现此类解决方案的示例代码:

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;
    }
}

答案 1 :(得分:1)

最简单的方法是将表单包装在< asp:UpdatePanel>中。这样,所有回发都是通过AJAX完成的,浏览器永远不会要求您重新提交表单。

答案 2 :(得分:0)

最好的两种方法是:

  1. 对数据库执行不同字段的检查

  2. 在使用基于时间的盐的表单中创建隐藏令牌。如果您在脚本中放置逻辑以检查现有时间并将其与令牌进行比较,则可以允许提交或定义它。例如,如果在特定时间绘制表单,则存储令牌,并且可以在30-60秒内提交,但之后您不能。