当用户点击浏览器的返回按钮时,防止页面重新提交

4
我有一个网页可以向多个用户(在线分发列表)发送电子邮件。当单击提交按钮并发送电子邮件后,会显示状态页面,列出已发送的电子邮件数量、错误和其他信息。如果用户单击后退按钮,则会重新发送电子邮件。如何防止这种情况发生?
注意:浏览器确实提示用户在实际发送电子邮件之前“重新提交”或“重新发送”数据到页面,但这不能阻止我的用户单击它,然后想知道为什么发送了两份电子邮件。
环境:
服务器:C#,ASP.NET 2.0,IIS6
客户端:任何浏览器(我不想使用IE特定的解决方案,如SmartNavigation)
1个回答

16

在您的代码中,在发送电子邮件之后,进行302重定向到确认页面:

protected void btnSend_Click(object sender, EventArgs e)
{
    SendManyEmails();
    Response.Redirect("confirmation.aspx");
}

使用这种代码的方式,原始页面的POST请求不会出现在浏览器历史记录中。

这种常见的模式被称为Post/Redirect/Get模式

关于在执行Post/Redirect/Get时保持状态的额外信息

这种模式的主要缺点是,在重定向用户时,来自处理POST请求的所有状态都会丢失-因此,开始一个新的请求上下文。在ASP.NET中,这包括Page中的成员和所有Control对象,以及存储在ViewState中的所有内容。

如果您在处理POST请求时生成某种“状态对象”(例如已发送电子邮件消息的日志),则需要某种方式将该对象保存以供以下GET请求使用。一些Web框架具有专门用于此目的的功能:RoR具有flash,ASP.NET MVC具有TempData。 ASP.NET表单中没有内置此类概念,因此您必须自己想出解决方法。

将对象保存到POST的Session中,在接下来的GET中读取和删除它将是解决此问题的一种方法。如果您在多个地方使用它,则可以围绕此构建一个抽象,或者您可以搜索现有的ASP.NET表单中基于flash / TempData的实现。


+1 对于教会我新东西的好回答。 :) 我真的应该更深入地了解Web开发。 - Greg D
1
+1,不错哦,我从来没有想过后退按钮的重新提交问题。非常棒! - Chuck Conway
可能会变成这样,但是如果进行重定向,我将失去在send()方法中生成的所有状态信息。那可能会带来很多开销。+1 - Rick
不错的。 每一天都是学校的日子。 - Sonny Boy
@Rick:我刚刚在我的回答中添加了一个奖励部分,涉及到你在最后一条评论中描述的情况。 - Jørn Schou-Rode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接