xujh
posts - 46, comments - 75, trackbacks - 5, articles - 1
【ASP.NET】防止ASP.NET按钮多次提交的办法
Posted on 2008-07-17 23:40
xujh
阅读(1974)
评论(25)
编辑
收藏
所属分类:
ASP.NET
网上查了很多方法,都不太好使,不如自己写一个,思路就是把按钮按下时用Javascript在客户端把按钮下一次的onclick事件改为return false; 这样在服务器端页面重新送回客户端之前,再次点击按钮都不会Post到服务端。同时将按钮的style改为一行字的样子,光标也变成沙漏状。当服务端页面重新产生后Button又会回到初始状态。该方法对于F5刷新还不能防范,只是简单封闭了F5的按键,为了防止刷新时再次提交可以在页面返回前将一些TextBox控件清空,这样就可以判断如果该TextBox为空则不再进行后续操作(如写库)。 或是后台操作成功后跳转到另一个页面以防止恶意刷新。主要是考虑在企业内网使用,不是为了防黑客,所以不是非常严格。
1
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
2
<
head
runat
="server"
>
3
<
title
>
禁止多次提交网页测试
</
title
>
4
<
style
type
="text/css"
>
5
.disable
6
{
}
{
7
border-style
:
none
;
8
border-width
:
thin
;
9
background-color
:
Transparent
;
10
color
:
#CCCCCC
;
11
cursor
:
wait
;
12
}
13
</
style
>
14
<
script
type
="text/javascript"
language
="javascript"
>
15
function
DisableButton()
16
{
17
document.getElementById(
"
Button2
"
).className
=
"
disable
"
;
18
document.getElementById(
"
Button2
"
).value
=
'
正在提交
.
'
;
19
document.getElementById(
"
Button2
"
).onclick
=
Function(
"
return false;
"
);
20
return
true
;
21
}
22
document.onkeydown
=
mykeydown;
23
function
mykeydown()
24
{
25
if
(event.keyCode
==
116
)
//
屏蔽F5刷新键
26
{
27
window.event.keyCode
=
0
;
28
return
false
;
29
}
30
}
31
</
script
>
32
33
</
head
>
34
<
body
>
35
<
form
id
="form1"
runat
="server"
>
36
<
div
>
37
输入一些内容
<
asp:TextBox
ID
="TextBox1"
runat
="server"
></
asp:TextBox
>
38
<
br
/>
39
<
asp:ListBox
ID
="ListBox1"
runat
="server"
Height
="77px"
Width
="332px"
>
40
</
asp:ListBox
><
br
/>
41
<
asp:Button
ID
="Button2"
runat
="server"
Text
="OK"
Width
="77px"
42
onclick
="Button2_Click"
/>
43
</
div
>
44
45
</
form
>
46
</
body
>
47
</
html
>
48
服务器端代码,故意让其延时等待3秒后再输入,以模拟数据库操作等慢速动作。
1
public
partial
class
Default2 : System.Web.UI.Page
2
{
3
static
public
int
count
=
0
;
4
protected
void
Page_Load(
object
sender, EventArgs e)
5
{
6
if
(
!
IsPostBack)
7
{
8
Button2.Attributes.Add(
"
onclick
"
,
"
return DisableButton();
"
);
9
}
10
}
11
12
protected
void
Button2_Click(
object
sender, EventArgs e)
13
{
14
if
(TextBox1.Text
!=
string
.Empty)
15
{
16
System.Threading.Thread.Sleep(
3000
);
17
count
++
;
18
ListBox1.Items.Add(
new
ListItem(
"
Hello
"
+
TextBox1.Text
+
"
这是你第
"
+
count.ToString()
+
"
次点击
"
+
DateTime.Now.ToString()));
19
TextBox1.Text
=
""
;
20
}
21
}
22
}
感谢网友大李的建议,<asp:Button ID="btnSumbit" runat="server" UseSubmitBehavior="false" OnClientClick="this.value='Sumbit';this.disabled=true; " Text="Sumbit" OnClick="btnSumbit_Click" />
这个方法比我的更好更简单
Tag标签:
防止ASP.NET按钮多次提交的办法
Feedback
#1楼
回复
引用
查看
2008-07-17 23:56 by
大李
<asp:Button ID="btnSumbit" runat="server" UseSubmitBehavior="false" OnClientClick="this.value='Sumbit';this.disabled=true; " Text="Sumbit" OnClick="btnSumbit_Click" />
用这个方法比较好,防止多次提交。
#2楼
回复
引用
查看
2008-07-18 05:14 by
Bewind
不错,我AJAX的时候,disable 在传出数据则 true 回调完成之后才 false.刷新,刷新后 input 自然是空值,提交数据前肯定要检测的,空值就传不上数据了。
#3楼
回复
引用
2008-07-18 08:16 by
JuzzPig [未注册用户]
如果是PostBack机制,这样防是远远不够的。不信,你提交后刷新页面试试。
#4楼
回复
引用
查看
2008-07-18 08:51 by
amingo
function mykeydown()
24 {
25 if(event.keyCode==116) //屏蔽F5刷新键
26 {
27 window.event.keyCode=0;
28 return false;
29 }
30 }
如果不能屏蔽菜单栏或反键中的刷新,有何意义?
#5楼
回复
引用
2008-07-18 08:59 by
vicps [未注册用户]
哈哈,试试在firefox下run.
#6楼
[
楼主
]
回复
引用
查看
2008-07-18 09:00 by
xujh
--引用--------------------------------------------------
amingo: function mykeydown()
24 {
25 if(event.keyCode==116) //屏蔽F5刷新键
26 {
27 window.event.keyCode=0;
28 return false;
29 }
30 }
如果不能屏蔽菜单栏或反键中的刷新,有何意义?
--------------------------------------------------------
谢谢,我的这个代码主要还是防止操作人员误操作。
#7楼
[
楼主
]
回复
引用
查看
2008-07-18 09:03 by
xujh
--引用--------------------------------------------------
JuzzPig: 如果是PostBack机制,这样防是远远不够的。不信,你提交后刷新页面试试。
--------------------------------------------------------
谢谢,PostBack后就可以进入服务端代码的控制中了,我这个范例中要求关键项必须填写才可以通过,在服务端处理并返回新的页面前可以通过清除关键输入项来使得刷新也无法进行后续处理。
#8楼
[
楼主
]
回复
引用
查看
2008-07-18 09:14 by
xujh
--引用--------------------------------------------------
大李:
用这个方法比较好,防止多次提交。
--------------------------------------------------------
谢谢大李,你这个方法更好。
#9楼
回复
引用
查看
2008-07-18 09:19 by
小龙3
--引用--------------------------------------------------
大李: <asp:Button ID="btnSumbit" runat="server" UseSubmitBehavior="false" OnClientClick="this.value='Sumbit';this.disabled=true; " Text="Sumbit" OnClick="btnSumbit_Click" />
用这个方法比较好,防止多次提交。
--------------------------------------------------------
简单!可行!
#10楼
回复
引用
查看
2008-07-18 09:39 by
chinaifne
这位老兄基本上没有用到asp.net里新增加的特性!
//.net1.1
Button1.Attributes.Add("onclick", "this.disabled=true;" + this.GetPostBackEventReference(this.Button1));
//.net 2.0以上
Button1.Attributes.Add("onclick", "this.disabled=true;" + this.ClientScript.GetPostBackEventReference(Button1, ""));
有这样的事件,可以用来处理。是真实的网页回发,比楼主的5秒要好些吧。
详细可以看我的博客:
http://www.cnblogs.com/chinafine/archive/2008/07/03/1234854.html
#11楼
回复
引用
查看
2008-07-18 10:06 by
S.Sams
#9楼 @小龙3
如果刷新又重复提交啦,
#1楼 + #4楼 结合是比较好的方案
#12楼
回复
引用
查看
2008-07-18 10:26 by
红尘中迷茫
直接Redirect页面不就行了吗?
#13楼
回复
引用
查看
2008-07-18 11:03 by
willieQ
我是直接使用JQuery
优点:不用每个按钮增加事件
缺点:不能避免刷新
但是一般为了根本解决重复提交,记录都是有版本号的,每次保存时自增,保存时需验证版本是否一致,也能防止多用户同时提交问题。
每次按钮点击后disable掉
$(document).ready(function(){
$("input").click(function(){
$(this).attr("disabled","disabled");
});
}
#14楼
回复
引用
2008-07-18 11:28 by
e1 [未注册用户]
恩,如果使用程序提交,好像是不管用的。
#15楼
回复
引用
2008-07-18 12:12 by
killer123 [未注册用户]
<asp:Button ID="btnSumbit" runat="server" UseSubmitBehavior="false" OnClientClick="this.value='Sumbit';this.disabled=true; " Text="Sumbit" OnClick="btnSumbit_Click" />
有验证控件就不行了~
#16楼
回复
引用
2008-07-18 12:18 by
killer123 [未注册用户]
jquery有验证控件就不行了~
#17楼
回复
引用
查看
2008-07-18 13:00 by
文炽城
这样的文章不应该放到首页上来吧。
#18楼
回复
引用
查看
2008-07-18 14:25 by
Henllyee Cui
@文炽城
您这样说就不太好了,我感觉只要是自己的心得体会就行了。
#19楼
回复
引用
查看
2008-07-18 15:04 by
吴畏
我不知道楼主有没有运行自己写的代码,通过清空数据来防止重复提交是行不通的,因为页面刷新是通过“ 简单”重复最新请求来实现的。换句话说,浏览器将缓存已处理的最新请求,并在用户单击页面刷新键时重新发布已处理的请求。
#20楼
回复
引用
查看
2008-07-18 15:27 by
∈鱼杆
--引用--------------------------------------------------
吴畏: 我不知道楼主有没有运行自己写的代码,通过清空数据来防止重复提交是行不通的,因为页面刷新是通过“ 简单”重复最新请求来实现的。换句话说,浏览器将缓存已处理的最新请求,并在用户单击页面刷新键时重新发布已处理的请求。
--------------------------------------------------------
我也发现大李提供的方法不行,页面已刷新了。
#21楼
回复
引用
2008-07-18 16:05 by
qisky [未注册用户]
加验证码,提交先就不能重复提交
#22楼
回复
引用
查看
2008-07-18 16:13 by
Microshaoft
通用的防止F5刷新,重复提交应该在服务器端代码控制!
结合【cookie 时间戳】与【隐藏域 时间戳】对比
我们只要把【cookie 时间戳】每次都刷新
当F5实际浏览器重复提交了上次的 【隐藏域 时间戳】
这种方案适用各种“自己提交给自己Action”的Web: PHP、ASP、JSP
#23楼
回复
引用
查看
2008-07-18 16:17 by
Microshaoft
<%
@ Page language
=
"
c#
"
AutoEventWireup
=
"
true
"
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
>
<
HTML
>
<
HEAD
>
<
title
>
WebForm1
</
title
>
<
meta
name
="GENERATOR"
Content
="Microsoft Visual Studio .NET 7.1"
>
<
meta
name
="CODE_LANGUAGE"
Content
="C#"
>
<
meta
name
="vs_defaultClientScript"
content
="JavaScript"
>
<
meta
name
="vs_targetSchema"
content
="http://schemas.microsoft.com/intellisense/ie5"
>
<
script
language
="C#"
runat
="server"
>
private bool _IsF5RefreshPostBack;
protected
void
Page_Load(object sender, EventArgs ea)
{
if
(IsPostBack)
{
if
(Request.Cookies[
"
cookieTimeStamp
"
]
!=
null
)
{
//
if (Request.Cookies["cookieTimeStamp"].Value != this.label1.Text)
//
不用ViewState 使用 HiddenField 也可
if
(Request.Cookies[
"
cookieTimeStamp
"
].Value
!=
(string) ViewState[
"
vsTimeStamp
"
])
{
_IsF5RefreshPostBack
=
true
;
}
}
}
string timeStamp
=
DateTime.Now.ToString();
//
this.label1.Text = timeStamp;
ViewState[
"
vsTimeStamp
"
]
=
timeStamp;
HttpCookie cookie
=
new
HttpCookie(
"
cookieTimeStamp
"
, timeStamp);
Response.Cookies.Add(cookie);
if
(_IsF5RefreshPostBack)
{
Response.Write(
"
IsRefreshPostBack(F5) in Page Load<br>
"
);
}
}
void
button1_Click (object sender, EventArgs ea)
{
if
(_IsF5RefreshPostBack)
{
Response.Write(
"
IsRefreshPostBack(F5) in Button Click<br>
"
);
}
}
</
script
>
</
HEAD
>
<
body
MS_POSITIONING
="GridLayout"
>
<
form
id
="Form1"
method
="post"
runat
="server"
>
<
asp:Button
ID
="button1"
Text
="button1"
onclick
="button1_Click"
runat
="server"
/>
</
form
>
</
body
>
</
HTML
>
#24楼
回复
引用
查看
2008-07-18 16:22 by
Microshaoft
还有一种方案:
就是不要“自己提交给自己”
可以使用@Page 页面指令 SmartNavigation Attribute
#25楼
[
楼主
]
回复
引用
查看
2008-07-19 14:05 by
xujh
呵呵,抛砖引玉。这个功能是大家都要用到的,但是可以看到这么多人有这么多种方法,而且各有优缺点。其他讨论出一个最优的方案来。
社区
新闻
新用户注册
刷新评论列表
标题
姓名
主页
Email
(只有博主才能看到)
验证码
*
看不清,换一张
[
登录
][
注册
]
内容(请不要发表任何与政治相关的内容)
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
该文被作者在 2008-07-18 09:19 编辑过
所属分类的其他文章:
·
一个正则表达式测试(只可输入中文、字母和数字)
·
IE6、7下如何设置页面内部件高度和窗口等高(heihgt:100%)
·
【ASP.NET】防止ASP.NET按钮多次提交的办法
·
【ASP.NET】FCKeditor 2.6 + Asp.Net 设置
·
【ASP.NET】FreeTextBox的使用方法
最新IT新闻:
·
第一财经周刊:当前互联网世界正处无秩序时代
·
Visual Studio 2008 SDK 1.1 发布
·
死敌VMware变身微软认证计划新成员
·
英特尔雅虎开发网络计算机频道
·
Windows Live视频邮件9月9日开始测试
博客园新闻频道
博客园首页
社区
Powered by:
博客园
Copyright © xujh
导航
博客园
首页
新随笔
联系
订阅
管理
<
2008年7月
>
日
一
二
三
四
五
六
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
与我联系
发短消息
搜索
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的参与
我的新闻
最新评论
我的标签
留言簿
(6)
给我留言
查看留言
我的标签
防止ASP.NET按钮多次提交的办法
(1)
双缓冲
(1)
height 100%
(1)
随笔分类
ASP.NET(5)
Delphi
移动开发(2)
随笔档案
2008年8月 (3)
2008年7月 (2)
2007年11月 (2)
2007年9月 (1)
2007年4月 (3)
2006年12月 (2)
2006年4月 (2)
2006年2月 (2)
2005年12月 (5)