如何解决用户点击浏览器的后退按钮造成的重复提交

tomiji 2009-03-26 08:59:35
这个是之前困扰了我比较长时间的一个问题,当时采取的是直接跳转到别的页面,不过感觉不是很妥当。
例如:在订单页面点击按钮提交了订单,后进入浏览已经提交的订单页面,但是点击后退后会造成重复提交。
大家可以交流下各自解决这个问题的方法
...全文
249 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Teng_s2000 2009-03-26
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090325/09/76b2590b-f4b8-420f-bee7-e4fdf77d78c6.html
奔跑的蜗牛007 2009-03-26
  • 打赏
  • 举报
回复
最好的方式,把浏览器窗口最大化,去掉所有的菜单和按钮,这样就不会存在什么问题.

另外,如果你采用AJAX技术,则在按钮提交成功后,使提交按钮变灰即可
zzxap 2009-03-26
  • 打赏
  • 举报
回复
[code=C#]
public class RefreshServe : System.Web.UI.Page
{
private static ILog log = LogManager.GetLogger(typeof(RefreshServe));

private readonly string REFRESH_TICKET_NAME = "__RefreshTicketArray";
private readonly string HIDDEN_FIELD_NAME = "__RefreshHiddenField";
private readonly string HIDDEN_PAGE_GUID = "__RefreshPageGuid";

/// <summary>
/// 为True表示页面刷新,False为正常提交
/// </summary>
public bool IsPageRefreshed
{
get
{
if (IsPostBack && !CheckRefreshFlag())
{
log.Debug("刷新了页面");
return true;
}
else
{
log.Debug("正常提交");
return false;
}
}
}

/// <summary>
/// 呈现前更新标识
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
log.Debug("执行OnPreRender");
base.OnPreRender(e);
UpdateRefreshFlag();
}


/// <summary>
/// 更新标识,正常提交都删除该次提交的时间,并生产当前新的时间
/// </summary>
private void UpdateRefreshFlag()
{

#region Cookie模式

//注册页面唯一标识并返回
string pageGuid = SetCurPageGuid();

HttpCookie cookie = GetRefreshTicket();

if (cookie.Values.Count > 0)
{
cookie.Values.Remove(pageGuid);
log.Debug("当前清除的cookie变是:" + pageGuid);
}

string submitTime = DateTime.Now.ToString("hhmmss.fffff");
//当前提交时间保存到隐藏域
ClientScript.RegisterHiddenField(HIDDEN_FIELD_NAME, submitTime);


log.Debug("即将要新增的时间:submitTime:" + submitTime + " Guid:" + pageGuid.ToString());
cookie.Values.Add(pageGuid, submitTime);

log.Debug("UpdateRefreshFlag中当前Cookie中存在的记录数为:" + cookie.Values.Count);
for (int i = 0; i < cookie.Values.Count; i++)
log.Info("cookie[" + cookie.Values.GetKey(i) + "]:" + cookie.Values[i]);

Response.AppendCookie(cookie);

#endregion

}


/// <summary>
/// 验证是否刷新
/// </summary>
/// <returns></returns>
private bool CheckRefreshFlag()
{
HttpCookie cookie = GetRefreshTicket();
string pageGuid = GetCurPageGuid();
if (cookie.Values.Count > 0)
{
bool flag;
if (cookie.Values[pageGuid] != null)
flag = cookie.Values[pageGuid].IndexOf(GetCurSubmitTime()) > -1;
else
flag = true;//防止出现异常,总是可以提交
if (flag)
log.Debug("提交时间存在,可以提交");
else
log.Debug("无效的提交时间");
return flag;
}
return true;
}


/// <summary>
/// 得到已保存的提交时间,没有新建,有返回
/// </summary>
/// <returns></returns>
private HttpCookie GetRefreshTicket()
{
#region Cookie模式,返回值为Cookie

HttpCookie cookie;
if (Request.Cookies[REFRESH_TICKET_NAME] == null)
{
cookie = new HttpCookie(REFRESH_TICKET_NAME);
Response.AppendCookie(cookie);
log.Debug("Cookie不存在,初始化");
}
else
{
cookie = Request.Cookies[REFRESH_TICKET_NAME];

log.Debug("读取已存在的Cookie,当前Cookie中存在的记录数为:" + cookie.Values.Count + "具体有如下几条:");

for (int i = 0; i < cookie.Values.Count; i++)
log.Info("cookie[" + cookie.Values.GetKey(i) + "]:" + cookie.Values[i]);
}
return cookie;
#endregion
}


/// <summary>
/// 获取当前提交时间
/// </summary>
/// <returns></returns>
private string GetCurSubmitTime()
{
string submitTime = Request.Params[HIDDEN_FIELD_NAME] == null ? "" : Request.Params[HIDDEN_FIELD_NAME].ToString();
log.Debug("执行GetCurSubmitTime:submitTime为:" + submitTime);
return submitTime;
}


/// <summary>
/// 设置页面唯一标识,通过Guid标识来区分每个页面自己的提交时间
/// </summary>
private string SetCurPageGuid()
{
string guid;
if (!IsPostBack)
{
if (Request.Params[HIDDEN_PAGE_GUID] == null)
{
guid = System.Guid.NewGuid().ToString();
log.Debug("SetCurPageGuid注册了一个新的标识:" + guid);
}
else
guid = GetCurPageGuid();

}
else
{
guid = GetCurPageGuid();
}

ClientScript.RegisterHiddenField(HIDDEN_PAGE_GUID, guid);
return guid;
}



/// <summary>
/// 得到当前页面的唯一标识
/// </summary>
/// <returns></returns>
private string GetCurPageGuid()
{
string pageGuid = Request.Params[HIDDEN_PAGE_GUID] == null ? "none" : Request.Params[HIDDEN_PAGE_GUID].ToString();
log.Debug("执行GetCurPageGuid()后Page_GUID为:" + pageGuid);
return pageGuid;
}

需要刷新判断功能时新页面只需继承该类就可,通过引用属性IsPageRefreshed识别"为真表示刷新,假则是正常提交",将数据库的操作写在
if(!IsPageRefreshed)
{
数据库操作
}
即可,如果是刷新不会执行,代码中注释部分使用的是Session方式保存票证,因为session比较容易丢失且占内存,所以使用cookie,

[/CODE]
wangzhenyue 2009-03-26
  • 打赏
  • 举报
回复
写JS控制
wangzhenyue 2009-03-26
  • 打赏
  • 举报
回复
可以在JS写方法..
Teng_s2000 2009-03-26
  • 打赏
  • 举报
回复
跳转前,强制Session过期!!

62,267

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧