Asp.Net防止刷新重复提交数据小记
2010-07-05 09:43
756 查看
在做项目的时候遇到这样的问题,网上找了下,觉得还可以,分享给大家
1楼
Asp.Net防止刷新重复提交数据小记
最近在用Asp.Net编写点东西时遇到个问题:即用户在提交表单后按刷新就会重复提交数据,即所谓的“刷
新重复提交”的问题。在网上搜 一下,可以找到很多关于这方面的资料,其中有一篇是来自MSDN上的一种
解决方法: http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dnvs05/html/BedrockASPNET.asp 它是通过重新定义 System.Web.UI.Page 类来实现加载页面时,是
“刷新”、“后退”请求,还是正常请求,其他的页面则继承了自定义的这 个Page类。感觉他这个方法比
较独特,有例子可以下载,有兴趣的可以研究研究。
网上最多的解决此类问题的方法就是不保存缓存,即提交后表单上的数据不会被浏览器的缓存保存,如果
此时再遇到刷新或者后退请求时, 就会显示“网页已过期”,数据也就不会重复提交了,这就起到了阻止
刷新重复提交的效果。
下面以简单的提交一篇帖子为例,介绍禁用缓存防止刷新重复提交的方法,表单数据包括“标题”和“正
文”两个部分。
以下是该方法的代码(post.aspx):
//页面加载
protected void Page_Load(object sender, EventArgs e)
{
//可以在页面加载时设置页面的缓存为“SetNoStore()”,即无缓存
Response.Cache.SetNoStore();
//Session中存储的变量“IsSubmit”是标记是否提交成功的
if ((bool)Session["IsSubmit"])
{
//如果表单数据提交成功,就设“Session["IsSubmit"]”为false
Session["IsSubmit"] = false;
//显示提交成功信息
ShowMsg.Text = " * 提交成功!";
}
else
//否则的话(没有提交,或者是页面刷新),不显示任何信息
ShowMsg.Text = "";
}
//提交按钮(btnOK)单击事件
protected void btnOK_Click(object sender, EventArgs e)
{
if (txtTitle.Text.ToString().Trim() == "")
//ShowMsg是用来显示提示信息的
ShowMsg.Text = " * 标题不能为空!";
else if (txtText.Text.ToString().Trim() == "")
ShowMsg.Text = " * 内容不能为空!";
else
{
//这里是将数据提交到数据库中,省略
/*
string sql = "insert into tab...values(...)";
MyConn.ExecQuery(sql);
*/
//提交成功后,设“Session["IsSubmit"]”为true
Session["IsSubmit"] = true;
//强制转换页面(不可少,否则刷新仍会重复提交,仍转到本页),
通过页面的转换将缓存中的提交的数据都释放了,即提交的标单数据不会被保存到缓存里,
如果后退的话,将会出现该页无法显示
Response.Redirect("post.aspx");
}
}
上面这个方法非常简单也很实用,推荐大家使用。
下面是我自己研究出来的另一种方法,该方法不同于“不保存缓存的方法”,它是让浏览器保存所有页面
缓存的。该方法通过随机码的方式 来判断是正常提交还是“刷新”或“后退”的。
首先(提交页面是post.aspx)在 Session 中 增加变量 Rnd 用来存放随机码,同时在提交表单数据
时不做处理,而是让页面转到 post.aspx?r=x,这里“x”等于Session["Rnd"],这个时候在页面加载时,
通过判断r的值和Session["Rnd"]的值是否相同,如果相同就处理提 交的数据,否则即可认为是“刷新”
或者是“后退”操作了,最后再次付给Session["Rnd"]一个随机码。
以下是该方法代码(post.aspx):
//获取随机码
public class MyRnd
{
public static string Rnd()
{
//随机码是由 0-9 a-z A-Z 之间的数字或字母组成的
//下面是生成的20位随机码
//0..9 A..Z a..z
//48-57 65-90 97-122
string rst = "";
Random rr = new Random();
for (int i = 0; i < 20; i++)
{
int ir = 0;
do
{
ir = rr.Next(123);
if((ir >= 48) && (ir <= 57)) break;
else if((ir >= 65) && (ir <= 90)) break;
else if ((ir >= 97) && (ir <= 122)) break;
}
while (true);
rst += ((char)ir).ToString();
}
return rst;
}
}
//页面加载
protected void Page_Load(object sender, EventArgs e)
{
//获取URL中请求的“r”值,如果“r”不存在则 r=""
string r = "";
if(Request.QueryString["r"] != null)
r = Request.QueryString["r"].ToString().Trim();
string t;
//获取 “Session” 中的 “Rnd” 值,用于和“r”比较
t = Session["Rnd"].ToString().Trim();
//如果“r=t”则为提交操作,即可对表单的数据进行处理
if(r == t)
{
if (txtTitle.Text.ToString().Trim() == "")
ShowMsg.Text = " * 标题不能为空!";
else if (txtText.Text.ToString().Trim() == "")
ShowMsg.Text = " * 内容不能为空!";
else {
//这里是将数据提交到数据库中,省略
/*
string sql = "insert into tab...values(...)";
MyConn.ExecQuery(sql);
*/
//提交成功后清空表单数据
txtTitle.Text = "";
txtText.Text = "";
//显示提交成功信息
ShowMsg.Text = " * 提交成功!";
}
}
//否则可以认为是“刷新”或者“后退”操作
else
{
txtTitle.Text = "";
txtText.Text = "";
}
//最后要重新获得“Session["Rnd"]”的值,并将“btnOK.PostBackUrl”设为“Session["Rnd"]”的值
Session["Rnd"] = MyRnd.Rnd();
btnOK.PostBackUrl ="post.aspx?r=" + Session["Rnd"].ToString().Trim();
}
//这里提交按钮(btnOK)单击事件就不需要写任何代码了
通过这种方法,每次加载页面时“Session["Rnd"]”都将得到一个新的值,而在刷新或后退时就不会得到
相同的“r”和“t”值,数据也就 不会被重复提交,只有通过“btnOK”来提交的操作才会得到“r==t”
,数据才会被提交处理的,通过判断随机码的方式来阻止刷新重复提交就 可以实现了。
1、提交后 禁用提交按钮(像CSDN这样)
2、数据处理成功马上跳转到另外一个页面!
操作后刷新的确是个问题,你可以使用跳转页面、关闭本页面,如果是有参数据条件来控制的,那就应该
好做了,可以直接修改window.location的值,把值的参数全部改掉,这样就可以了。我用的方法就是以上
的。
document.all("save_"+idx).disabled=true;
刚才有位兄弟也这么问其实很简单
在提交的页面也就是数据库处理之前
if session("jy")=true then
response.write "错误,正在提交"
response.end
end if
在数据库处理完毕后,释放session("jy")
session("jy")=false
即可!
用SESSION 或者用个麻烦点的方法:
用window.open 弹出表单输入页面,点提交后关闭该页;
处理提交的ASP页也是用弹出,即先设定表单的target为"submit_form",点提交时window.open
("XXX.asp","submit_form"),然后用JS来提交表单,最后就是window.close();
对处理提交的ASP页,输入数据到数据库完成后,弹出对话框,“提交成功”什么的,最后也来个
window.close();
因为对于window.open()打开的窗口,用window.close()来关闭时不会弹出提示框,直接就关闭窗口了,这
样用户就根本没有机会做重复提交了。
不知道这样合不合你的意思
2、数据处理成功马上跳转到另外一个页面!
这个方法最简单
转:(原理借用)
首先,我们可以定义一个session变量用来保存一个表单的提交序列号。这里我定义为“$userLastAction
”。然后在表单里加入一个hidden变量,把值设为$userLastAction+1:
<input type=Hidden name=lastAction value=<? =$userLastAction+1 ?>>
最后,在处理提交之前判断表单是否已被提交过:
if($lastAction>$userLastAction and inputIsValid(...)){
$userLastAction++; // 序列号加1
// 处理表单数据
}
我一直使用这个
你的后台处理页面,也就是数据接收页面,执行完相关的操作后,使用下面的语句:
response.write("<script>alert('数据提交成功******');window.location.href='你想要转向的页面的
地址';</script>")
这样随便他返回后怎么刷新,显示的始终是“数据提交成功******”的对话框
Top
回复人:arcow(冲星) ( ) 信誉:100 2004-10-24 17:09:40 得分:0
?
<SCRIPT LANGUAGE="javascript">
<!--
function input(ok)
{
var M1=ok.ReplyContent.value;
if (M1==''){
alert('回复内容不可以为空.');
return false;
}
ok.B1.disabled =true;
ok.B2.disabled =true;
return true;
}
//-->
</script>
<form onsubmit="return input(this)">
<input type=text name=ReplyContent>
<input type="submit" value="发出回复" border="0" name="B1">
<input name="B2" TYPE="reset"value="重 写">
</form>
这样就行了,提交后直接转到另一页面
1、让提交后返回历史记录
Response.Write"<script>alert('OK!添加成功!');history.back();</script>"
2、提交后跳转到本页
response.redirect "index.asp"
Response.Write"<script language=javascript>alert('提交成
功!');window.location.href='"&Request.ServerVariables("Http_Referer")&"';</script>"
===========================================
防止网页后退
我们在进行数据库添加操作的时候,如果允许后退,而正巧有刷新了页面,就会再次执行添加操作,无疑
这不是我们需要的,像一般网上很多禁止缓存的代码,有时并不可靠,这时你只要在操作的页面加上<body
onbeforeunload="window.location.replace('')">就可以了,在网页的里指定要定向的新页,再点后退,
看是不是不会再退到刚才的操作页面了,实际上已经把这个历史给删除了
============================
Response.Buffer=true;
Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);
Response.Expires=0;
Response.CacheControl="no-cache";
==========
1。在asp.net页面中的HTML处插入如下代码:
<input id="hiddenTest" type="hidden" value="<%= GetToken() %>" name="hiddenTestN"/>
2。在page_load里写上如下代码:
//*******防页面刷新
if (null == Session["Token"])
{
SetToken();
}
//***********
3。CS页面里加上如下方法
public string GetToken()
{
if (null != Session["Token"])
{
return Session["Token"].ToString();
}
else
{
return string.Empty;
}
}
private void SetToken()
{
Session.Add("Token", UserMd5(Session.SessionID + DateTime.Now.Ticks.ToString()));
}
protected string UserMd5(string str1)
{
string cl1 = str1;
string pwd = "";
MD5 md5 = MD5.Create();
// 加密后是一个字节类型的数组
byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl1));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写
(X)则格式后的字符是大写字符
pwd = pwd + s[i].ToString("X");
}
return pwd;
}
4。在要防刷新的地方写上:
//*******防页面刷新
if (!Request.Form.Get("hiddenTestN").Equals(GetToken()))
{
return;
}
SetToken();
//***********
1楼
Asp.Net防止刷新重复提交数据小记
最近在用Asp.Net编写点东西时遇到个问题:即用户在提交表单后按刷新就会重复提交数据,即所谓的“刷
新重复提交”的问题。在网上搜 一下,可以找到很多关于这方面的资料,其中有一篇是来自MSDN上的一种
解决方法: http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dnvs05/html/BedrockASPNET.asp 它是通过重新定义 System.Web.UI.Page 类来实现加载页面时,是
“刷新”、“后退”请求,还是正常请求,其他的页面则继承了自定义的这 个Page类。感觉他这个方法比
较独特,有例子可以下载,有兴趣的可以研究研究。
网上最多的解决此类问题的方法就是不保存缓存,即提交后表单上的数据不会被浏览器的缓存保存,如果
此时再遇到刷新或者后退请求时, 就会显示“网页已过期”,数据也就不会重复提交了,这就起到了阻止
刷新重复提交的效果。
下面以简单的提交一篇帖子为例,介绍禁用缓存防止刷新重复提交的方法,表单数据包括“标题”和“正
文”两个部分。
以下是该方法的代码(post.aspx):
//页面加载
protected void Page_Load(object sender, EventArgs e)
{
//可以在页面加载时设置页面的缓存为“SetNoStore()”,即无缓存
Response.Cache.SetNoStore();
//Session中存储的变量“IsSubmit”是标记是否提交成功的
if ((bool)Session["IsSubmit"])
{
//如果表单数据提交成功,就设“Session["IsSubmit"]”为false
Session["IsSubmit"] = false;
//显示提交成功信息
ShowMsg.Text = " * 提交成功!";
}
else
//否则的话(没有提交,或者是页面刷新),不显示任何信息
ShowMsg.Text = "";
}
//提交按钮(btnOK)单击事件
protected void btnOK_Click(object sender, EventArgs e)
{
if (txtTitle.Text.ToString().Trim() == "")
//ShowMsg是用来显示提示信息的
ShowMsg.Text = " * 标题不能为空!";
else if (txtText.Text.ToString().Trim() == "")
ShowMsg.Text = " * 内容不能为空!";
else
{
//这里是将数据提交到数据库中,省略
/*
string sql = "insert into tab...values(...)";
MyConn.ExecQuery(sql);
*/
//提交成功后,设“Session["IsSubmit"]”为true
Session["IsSubmit"] = true;
//强制转换页面(不可少,否则刷新仍会重复提交,仍转到本页),
通过页面的转换将缓存中的提交的数据都释放了,即提交的标单数据不会被保存到缓存里,
如果后退的话,将会出现该页无法显示
Response.Redirect("post.aspx");
}
}
上面这个方法非常简单也很实用,推荐大家使用。
下面是我自己研究出来的另一种方法,该方法不同于“不保存缓存的方法”,它是让浏览器保存所有页面
缓存的。该方法通过随机码的方式 来判断是正常提交还是“刷新”或“后退”的。
首先(提交页面是post.aspx)在 Session 中 增加变量 Rnd 用来存放随机码,同时在提交表单数据
时不做处理,而是让页面转到 post.aspx?r=x,这里“x”等于Session["Rnd"],这个时候在页面加载时,
通过判断r的值和Session["Rnd"]的值是否相同,如果相同就处理提 交的数据,否则即可认为是“刷新”
或者是“后退”操作了,最后再次付给Session["Rnd"]一个随机码。
以下是该方法代码(post.aspx):
//获取随机码
public class MyRnd
{
public static string Rnd()
{
//随机码是由 0-9 a-z A-Z 之间的数字或字母组成的
//下面是生成的20位随机码
//0..9 A..Z a..z
//48-57 65-90 97-122
string rst = "";
Random rr = new Random();
for (int i = 0; i < 20; i++)
{
int ir = 0;
do
{
ir = rr.Next(123);
if((ir >= 48) && (ir <= 57)) break;
else if((ir >= 65) && (ir <= 90)) break;
else if ((ir >= 97) && (ir <= 122)) break;
}
while (true);
rst += ((char)ir).ToString();
}
return rst;
}
}
//页面加载
protected void Page_Load(object sender, EventArgs e)
{
//获取URL中请求的“r”值,如果“r”不存在则 r=""
string r = "";
if(Request.QueryString["r"] != null)
r = Request.QueryString["r"].ToString().Trim();
string t;
//获取 “Session” 中的 “Rnd” 值,用于和“r”比较
t = Session["Rnd"].ToString().Trim();
//如果“r=t”则为提交操作,即可对表单的数据进行处理
if(r == t)
{
if (txtTitle.Text.ToString().Trim() == "")
ShowMsg.Text = " * 标题不能为空!";
else if (txtText.Text.ToString().Trim() == "")
ShowMsg.Text = " * 内容不能为空!";
else {
//这里是将数据提交到数据库中,省略
/*
string sql = "insert into tab...values(...)";
MyConn.ExecQuery(sql);
*/
//提交成功后清空表单数据
txtTitle.Text = "";
txtText.Text = "";
//显示提交成功信息
ShowMsg.Text = " * 提交成功!";
}
}
//否则可以认为是“刷新”或者“后退”操作
else
{
txtTitle.Text = "";
txtText.Text = "";
}
//最后要重新获得“Session["Rnd"]”的值,并将“btnOK.PostBackUrl”设为“Session["Rnd"]”的值
Session["Rnd"] = MyRnd.Rnd();
btnOK.PostBackUrl ="post.aspx?r=" + Session["Rnd"].ToString().Trim();
}
//这里提交按钮(btnOK)单击事件就不需要写任何代码了
通过这种方法,每次加载页面时“Session["Rnd"]”都将得到一个新的值,而在刷新或后退时就不会得到
相同的“r”和“t”值,数据也就 不会被重复提交,只有通过“btnOK”来提交的操作才会得到“r==t”
,数据才会被提交处理的,通过判断随机码的方式来阻止刷新重复提交就 可以实现了。
1、提交后 禁用提交按钮(像CSDN这样)
2、数据处理成功马上跳转到另外一个页面!
操作后刷新的确是个问题,你可以使用跳转页面、关闭本页面,如果是有参数据条件来控制的,那就应该
好做了,可以直接修改window.location的值,把值的参数全部改掉,这样就可以了。我用的方法就是以上
的。
document.all("save_"+idx).disabled=true;
刚才有位兄弟也这么问其实很简单
在提交的页面也就是数据库处理之前
if session("jy")=true then
response.write "错误,正在提交"
response.end
end if
在数据库处理完毕后,释放session("jy")
session("jy")=false
即可!
用SESSION 或者用个麻烦点的方法:
用window.open 弹出表单输入页面,点提交后关闭该页;
处理提交的ASP页也是用弹出,即先设定表单的target为"submit_form",点提交时window.open
("XXX.asp","submit_form"),然后用JS来提交表单,最后就是window.close();
对处理提交的ASP页,输入数据到数据库完成后,弹出对话框,“提交成功”什么的,最后也来个
window.close();
因为对于window.open()打开的窗口,用window.close()来关闭时不会弹出提示框,直接就关闭窗口了,这
样用户就根本没有机会做重复提交了。
不知道这样合不合你的意思
2、数据处理成功马上跳转到另外一个页面!
这个方法最简单
转:(原理借用)
首先,我们可以定义一个session变量用来保存一个表单的提交序列号。这里我定义为“$userLastAction
”。然后在表单里加入一个hidden变量,把值设为$userLastAction+1:
<input type=Hidden name=lastAction value=<? =$userLastAction+1 ?>>
最后,在处理提交之前判断表单是否已被提交过:
if($lastAction>$userLastAction and inputIsValid(...)){
$userLastAction++; // 序列号加1
// 处理表单数据
}
我一直使用这个
你的后台处理页面,也就是数据接收页面,执行完相关的操作后,使用下面的语句:
response.write("<script>alert('数据提交成功******');window.location.href='你想要转向的页面的
地址';</script>")
这样随便他返回后怎么刷新,显示的始终是“数据提交成功******”的对话框
Top
回复人:arcow(冲星) ( ) 信誉:100 2004-10-24 17:09:40 得分:0
?
<SCRIPT LANGUAGE="javascript">
<!--
function input(ok)
{
var M1=ok.ReplyContent.value;
if (M1==''){
alert('回复内容不可以为空.');
return false;
}
ok.B1.disabled =true;
ok.B2.disabled =true;
return true;
}
//-->
</script>
<form onsubmit="return input(this)">
<input type=text name=ReplyContent>
<input type="submit" value="发出回复" border="0" name="B1">
<input name="B2" TYPE="reset"value="重 写">
</form>
这样就行了,提交后直接转到另一页面
1、让提交后返回历史记录
Response.Write"<script>alert('OK!添加成功!');history.back();</script>"
2、提交后跳转到本页
response.redirect "index.asp"
Response.Write"<script language=javascript>alert('提交成
功!');window.location.href='"&Request.ServerVariables("Http_Referer")&"';</script>"
===========================================
防止网页后退
我们在进行数据库添加操作的时候,如果允许后退,而正巧有刷新了页面,就会再次执行添加操作,无疑
这不是我们需要的,像一般网上很多禁止缓存的代码,有时并不可靠,这时你只要在操作的页面加上<body
onbeforeunload="window.location.replace('')">就可以了,在网页的里指定要定向的新页,再点后退,
看是不是不会再退到刚才的操作页面了,实际上已经把这个历史给删除了
============================
Response.Buffer=true;
Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);
Response.Expires=0;
Response.CacheControl="no-cache";
==========
1。在asp.net页面中的HTML处插入如下代码:
<input id="hiddenTest" type="hidden" value="<%= GetToken() %>" name="hiddenTestN"/>
2。在page_load里写上如下代码:
//*******防页面刷新
if (null == Session["Token"])
{
SetToken();
}
//***********
3。CS页面里加上如下方法
public string GetToken()
{
if (null != Session["Token"])
{
return Session["Token"].ToString();
}
else
{
return string.Empty;
}
}
private void SetToken()
{
Session.Add("Token", UserMd5(Session.SessionID + DateTime.Now.Ticks.ToString()));
}
protected string UserMd5(string str1)
{
string cl1 = str1;
string pwd = "";
MD5 md5 = MD5.Create();
// 加密后是一个字节类型的数组
byte[] s = md5.ComputeHash(Encoding.Unicode.GetBytes(cl1));
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写
(X)则格式后的字符是大写字符
pwd = pwd + s[i].ToString("X");
}
return pwd;
}
4。在要防刷新的地方写上:
//*******防页面刷新
if (!Request.Form.Get("hiddenTestN").Equals(GetToken()))
{
return;
}
SetToken();
//***********
相关文章推荐
- Asp.Net防止刷新重复提交数据小记(摘自网上,具体出处不记得了,而且对其内容还没实践,暂且收入再说)
- Asp.Net防止刷新重复提交数据小记
- asp.net防止页面刷新引起重复提交数据
- Asp.Net防止刷新重复提交数据(小记)
- Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据小记(转自网上)
- Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据
- Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据小记
- 移动项目开发笔记(asp.net防止页面刷新引起重复提交数据)
- (转载)Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据的办法
- ASP.net关于防止刷新重复提交数据
- Asp.Net防止刷新重复提交数据
- Asp.Net防止刷新重复提交数据的办法
- Asp.Net防止刷新重复提交数据小记
- Asp.Net防止刷新重复提交数据