艾伟:彻底解决刷新重复提交问题,你还在用Response.Redirect吗?
以前也研究过,始终没找到好的办法,看了微软Msdn上的解决方案,使用后发现存在较多漏洞,考虑的情况太少,如页面加载后没有提交,始终刷新,在同一浏览器打开多个各选项卡,每个选项卡打开同一页面或不同页面,以下是我的解决方案,
Code
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,
转载于:https://www.cnblogs.com/waw/archive/2011/08/29/2156937.html
艾伟:彻底解决刷新重复提交问题,你还在用Response.Redirect吗?相关推荐
- JSP 防止网页刷新重复提交数据
网页如何防止刷新重复提交与如何防止后退的解决方法 提交后禁用提交按钮(大部分人都是这样做的) 如果客户提交后,按F5刷新怎么办? 使用Session 在提交的页面也就是数据库处理之前: if sess ...
- 如何解决ajax重复提交的问题
如何解决ajax重复提交的问题 参考文章: (1)如何解决ajax重复提交的问题 (2)https://www.cnblogs.com/xuyan1/p/6256876.html 备忘一下.
- Asp.Net防止刷新重复提交数据的办法
Asp.Net防止刷新重复提交数据的办法 转载于:https://www.cnblogs.com/u137578217/p/3388797.html
- php页面防刷,PHP防止刷新重复提交页面的示例代码
PHP防止刷新重复提交页面的示例代码 作为phper,我们在开发和学习php过程中,难免要经常的接受处理表单数据,然而处理表单的时候总会有一个问题,困扰大家,刷新页面重复提交的问题.如何防止刷新页面重 ...
- mysql 防重复提交_怎样防止刷新重复提交、防后退
怎样防止刷新重复提交.防后退 提交后禁用提交按钮 1.如果提交后,按F5刷新怎么办? 使用Session 在提交的页面也就是数据库处理之前: if session("ok")=tr ...
- php 防止刷新重复提交,php防止刷新与重复提交实例代码
防止直接访问PHP页面,只能引用!这样就不能直接访问B页面了. 也可以在A加COOKIE,B判断COOKIE后用完删掉COOKIE 防止刷新模块 所以就考虑增加一个参数来防止这类情况的发生,COOKI ...
- ASP.Net防止页面刷新重复提交
在asp.net中页面刷新则会出现重复提交问题 解决方法一:提交完成后跳转至新页面 解决方法二:网站找的,代码如下 namespace StevenBey.Web.UI { public class ...
- SpringBoot解决用户重复提交订单(方式一:通过唯一索引实现)
文章目录 前言 1.方案实现 1.1.给数据库表增加唯一键约束 1.2.编写获取请求唯一ID的接口 1.3.业务提交的时候,检查唯一ID 2.小结 前言 对于投入运营的软件系统(商城.物流.工厂等), ...
- Strust2用户注册,使用token防止刷新重复提交
1. 别忘记在jsp页面头部加入 <%@ taglib uri="/struts-tags" prefix="s" %> 2. 在form或< ...
最新文章
- C# WinForm 弹出模式窗口操作滚动条
- 知识付费为何从一个“圈粉”的事业变成一个“骗粉”的勾当?
- Swoole跨域问题解决
- 如何获取网站icon
- Flutter文本输入框TextField控制器TextEditingController,TextField预设内容,获取TextField中的输入内容,兼听TextField中的内容变化
- linux中 centos6 文件误删如何恢复
- 正则表达式学习笔记008--字符组简记法2
- 【iOS-cocos2d-X 游戏开发之八】使用Lua脚本进行游戏开发(基础篇)
- LeetCode 1——两数之和
- python向数据库中添加参数_python往mysql数据库中写入数据和更新插入数据
- Qt QLabel 文字滚动 滚动字幕
- 新版 世界地图 中文版地图 国界地图 高清全彩矢量地图 CDR 2021年整理制作
- 通俗易懂讲解javaSocket编程
- IDEA项目启动配置
- 敏捷教练如何辅导发布计划的制定之开展行动
- 客制化机械键盘改键软件VIA介绍
- 福大计算机课程表,福州大学研究生院-通知公告-福州大学课程表(非全日制工程硕士研究生2017年周末班公共课3-5月份 )...
- 湖仓一体化:铁打的数据仓 流水的数据湖产品
- Spring MVC框架中关于限制请求方式
- docx_demos(创建文档类Document及属性方法, 创建段落文本类Paragraph及段落格式设置, 创建字体设置类Run及属性等)
热门文章
- 大数据之-Hadoop3.x_HDFS_数据完整性_HDFS的CRC数据校验---大数据之hadoop3.x工作笔记0078
- k8s核心技术-Ingress(对外暴露应用实施)---K8S_Google工作笔记0042
- k8s核心技术-Pod(调度策略)_影响Pod调度(污点和污点容忍)---K8S_Google工作笔记0027
- MFC工作笔记0001---认识MFC
- Linux学习笔记005----CentOS7 vi模式保存并退出
- WebStorm学习笔记002---grunt-watch插件的使用-修改html,css,js文件实现自动编译更新
- Maven异常总结001---Maven project导入到myeclipse时候出现异常:could not get mojo execution paramater value
- 杭电2112HDU Today(map 最短路径)
- php调用shell的方法
- 将C/C++代码中的注释删除