【问题标题】:How to prevent a user from resubmitting a form?如何防止用户重新提交表单?
【发布时间】:2014-07-30 15:02:50
【问题描述】:

我正在开发一个单页应用程序

在应用程序结束时,用户可以提交他的联系信息(姓名、电话号码等)。这会发送一封电子邮件并将页面修改为“感谢提交 [...]”页面。

问题是,客户端可以按返回按钮并重新发送电子邮件。

有没有办法防止这种垃圾邮件?

代码

Sub BT_Send(sender As Object, e As EventArgs) Handles BT_Send.Click
Try
    'Creating the Email Message
    Dim mailMessage As New MailMessage()
    mailMessage.To.Add("SomeOne@a.com")
    mailMessage.From = New MailAddress("Robot@a.com", "Robot")
    mailMessage.Subject = "Test"
    mailMessage.IsBodyHtml = True
    mailMessage.Body = LBL_Emailbody.Text & _
        "<br><br><br><div style=""font-size: 0.7em;"">Robot speaking, I will not answer if you send me a message.</div>"
    Dim smtpClient As New SmtpClient("Something.com")
    smtpClient.Send(mailMessage)


    PNL_Before.Visible = False
    PNL_After.Visible = True
Catch ex As Exception
    LBL_errorEmail.Visible = True
    'Should never happen...
End Try
End sub

【问题讨论】:

  • 您可以存储一个cookie来表明用户已经使用了表单,当您检测到该cookie时,不允许该表单。
  • 有一些方法...您可以保留用户发送的最后一封电子邮件,并避免重新发送非常接近的联系人。
  • @fahadash 如果用户禁用了 cookie 怎么办?
  • @Aristos 保留最后一封电子邮件在哪里? (如果你的意思是把它放在接收端,那么他仍然可以发送它。如果它带有 cookie,用户可以禁用 cookie 并仍然这样做)
  • 您可以将它们保存在数据库中,如果您没有数据库,一种快速简便的方法是保存在静态变量上(例如字典)。静态变量可以保存每个池的最后一封电子邮件,并且在重新编译时会丢失,但您可以做一些工作。

标签: asp.net vb.net single-page-application


【解决方案1】:

这是一个非常简单的示例,我在页面上使用静态变量并避免使用数据库。

asp.net 页面是

<asp:Literal runat="server" ID="txtInfos"></asp:Literal><br />
<asp:TextBox runat="server" ID="txtEmail"></asp:TextBox><br />
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />/>

以及背后的代码。

static Dictionary<string, DateTime> cLastSubmits = new Dictionary<string, DateTime>();

private static readonly object syncLock = new object();

protected void Button1_Click(object sender, EventArgs e)
{
    DateTime cWhenLast;

    lock (syncLock)
    {
        var cNowIs = DateTime.UtcNow;
        if (cLastSubmits.TryGetValue(txtEmail.Text, out cWhenLast))
        {
            if (cWhenLast > cNowIs )
            {
                txtInfos.Text = "Please contact us again after 10 seconds";
                return;
            }
            else
            {
                // ok I let him submit the form, but note the last date time.
                cLastSubmits.Remove(txtEmail.Text);
            }
        }

        foreach(var DelMe in cLastSubmits.Where(x => cNowIs > x.Value).ToList())
            cLastSubmits.Remove(DelMe.Key);

        // if reach here, note the last datetime of submit            
        cLastSubmits.Add(txtEmail.Text, cNowIs.AddSeconds(10));
    }

    // and submit the form.
    txtInfos.Text = "thank you for submit the form";
}

一些笔记。

【讨论】:

  • 非常有趣!我已经知道 honey pot trickcaptcha。我不必保护自己免受机器人的侵害,因为用户必须使用经过验证的电子邮件帐户注册才能发送电子邮件。我试图理解dictionnaries,但我似乎无法理解它存储在哪里? (因为在每次回发时,每个变量都是空的)
  • @Sifu 我已经进行了更新以清除旧数据。看,我把它设置为静态的,所以它自己存储在 asp.net 池的全局数据中。
  • @Sifu 试试看,它很酷,而且很好用 :) 我已经完成并测试了。
  • 我明白了!感谢您花时间写这篇文章。我将使用它来防止多次发送。
猜你喜欢
  • 2011-04-24
  • 1970-01-01
  • 2019-03-28
  • 2019-07-20
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
相关资源
最近更新 更多