找回密码
 入住遨海湾
搜索
网站解决方案专享优惠-3折上云
查看: 1820|回复: 2

网页防刷新重复提交、防后退解决方法

[复制链接]
发表于 2008-1-9 10:09:00 | 显示全部楼层 |阅读模式

登录后查才能浏览下载更多咨询,有问题联系QQ:3283999

您需要 登录 才可以下载或查看,没有账号?入住遨海湾

×
提交后禁用提交按钮(大部分人都是这样做的)+ |4 H9 l" _- i+ \9 E& _ 3 c2 _7 ?, o# ?# f3 K9 y4 ^1 g 如果客户提交后,按F5刷新怎么办?8 u0 }# ? H" c9 N! `& E- G + ?$ ]' A4 X5 j! _9 s Z0 G/ G使用Session( b. l& m0 A: p: o, S2 [, [ 1 j' N0 S6 p' Y! G/ C' w+ ` L 在提交的页面也就是数据库处理之前:( O3 G+ @6 ^ {/ L- b ^# r; B & l$ T8 j6 }0 L1 \if session("ok")=true then6 J$ Q1 I4 w$ _% I% I response.write "错误,正在提交" ' }0 |& Q# X; P response.end 6 T* ~: B5 N/ w& O0 J: fend if 3 N b: N* V, c0 {% y% `2 F! J* r1 a( g: s8 O4 E 数据处理完后,修改session("ok")=false。 / ?+ j# r. h' ~1 u( t2 s; k9 B7 E# y$ A3 F. T 数据处理成功马上Redirect到另外一个页面. D) j7 c+ s. d# g $ m& a- N$ y! i操作后刷新的确是个问题,你可以使用跳转页面、关闭本页面,如果是有参数据条件来控制的,那就应该好做了,可以直接修改window.location的值,把参数全部改掉,这样就差不多了。 " D9 h0 H$ M' B$ M; j ! t9 t0 Y5 {, N2 R6 ^. B6 u/ \ 缺点:简单地运用Response.Redirect将不再有效,因为用户从一个页面转到另一个页面,我们都必须用客户端代码清除location.history。注意,这种方法清除的是最后一个访问历史记录,而不是全部的访问记录。 点击后退按钮,再点击后退按钮,你可以看到这时打开的是本页面之前的页面!(当然,这是在你的客户端启用了JavaScript功能的条件下。) ) n. Q+ I- @7 E/ `1 y1 n. i1 P" b 如果客户按后退,怎么办? 7 l% C5 e6 J, [6 Z' [, |" f 9 T# b; o3 z9 S2 y! [防止网页后退--禁止缓存 6 [$ ^, w$ P. _# b J+ c 8 o2 A9 J- c, Q2 }# ?( q& W) o我们在进行数据库添加操作的时候,如果允许后退,而正巧有刷新了页面,就会再次执行添加操作,无疑这不是我们需要的,像一般网上很多禁止缓存的代码,有时并不可靠,这时你只要在操作的页面加上就可以了,在网页的里指定要定向的新页,再点后退,看是不是不会再退到刚才的操作页面了,实际上已经把这个历史给删除了 * B# v6 [1 D B" E6 M. |* S " u1 r* F5 ]3 I5 l3 N4 _* hASP: 8 w Z8 T; u# n! P/ kResponse.Buffer = True 5 d' i7 h9 Z9 A' z u1 KResponse.ExpiresAbsolute = Now() - 1 9 z7 c( e$ x, m4 B, t( A) ?0 aResponse.Expires = 0 * n5 f1 i; }+ z( B) ?7 x Response.CacheC 2 H1 K: d3 M) }8 y" X4 N3 F1 N; E" m. c) \/ L ASP.NET: ( ]2 Z- @1 L% Z5 ^2 E- xResponse.Buffer=true;' n, ~; U' f9 A! @( [ Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);; t8 v7 \% F X7 \/ `- K' \" x Response.Expires=0; / C0 n6 G, _2 \' ?9 f- ` uResponse.CacheC; 3 U/ D h8 }! z$ {: k' ?; \ 1 Q# S0 v+ r' j, I( E' ~究竟怎样才能"禁用"浏览器的后退按钮?或者“怎样才能防止用户点击后退按钮返回以前浏览过的页面?” 3 J" K6 V0 A& Z7 ^2 Q" l0 d$ \ B3 y 遗憾的是,我们无法禁用浏览器的后退按钮。0 } G) e( q& t$ M9 C& U8 u ' S- F9 F& @; `1 b 防止网页后退--新开窗口' Z+ t" e8 P- V. V+ Y+ @; q . d" I! w5 K/ V6 m( z1 J 用window.open弹出表单页面,点提交后关闭该页;处理提交的ASP页也是用弹出,设定表单的target,点提交时window.open("XXX.asp","_blank"),然后用JS来提交表单,完成后window.close();# N* |- n }; D$ y$ q. w 简单的说,就是提交表单的时候弹出新窗口,关闭本窗口。对于window.open()打开的窗口怎么后退?能后退到哪里去?+ W$ [4 E# g& w/ O , g e- h: f; f又一个新方法,放在ASP页面前面就可以了,其他如JSP也可以仿照一下~~$ w0 k d# ^& K) M, Q9 Q% I$ m . ~/ B" `+ b) y<% 3 k! j; S8 ^% q. t! C" odim RefreshIntervalTime , h+ c! z# Y3 V! q) t2 JRefreshIntervalTime = 3 '防止刷新的时间秒数,0表示不防止 8 U& q* X! |' r2 b1 r9 V( D( `$ v0 iIf Not IsEmpty(Session("visit")) and isnumeric(Session("visit")) and int(RefreshIntervalTime) > 0 Then& T- m9 Y% b" ?2 P0 s: e$ N if (timer()-int(Session("visit")))*1000 < RefreshIntervalTime * 1000 then $ J' v8 @( V8 O* W Response.write ("<meta http-equiv=""refresh"" c"& RefreshIntervalTime &""" />") 0 L1 o$ i! Y0 v8 i" l& V Response.write ("刷新过快,请稍候")" s. v, R; ^4 M: A Session("visit") = timer() 1 N2 L; O8 x j Response.end 3 i8 N. D& K5 f3 n2 Q; X- `end if 1 ]6 W% I. t$ s7 r- ]End If - [8 B+ T3 w' sSession("visit") = timer() 5 c" L/ I* f" i* Q- E; ~+ \%>
遨海湾-心灵的港湾 www.aosea.com
 楼主| 发表于 2008-1-9 10:11:00 | 显示全部楼层

5秒内不能刷新本页

<% # D, @; |3 ?: Q( o9 Z8 N |" A# s, y if DateDiff("s",session("time"),now())<5 then " Z9 k4 u' ^5 L: v response.write("<script>alert('不能在5秒内重新打开此页');</script") : V9 a5 K" ]- ?5 {6 E1 R7 F0 {5 E4 G else 5 K, }6 T+ u0 q; F/ G8 m+ f session("time")=now(); - S0 k) \+ n7 R- X4 Y7 _ end if 7 m$ j8 n1 S+ c %>
遨海湾-心灵的港湾 www.aosea.com
回复

使用道具 举报

 楼主| 发表于 2008-1-9 10:14:00 | 显示全部楼层

回复:网页防刷新重复提交、防后退解决方法

用ASP.NET开发的人对服务器端控件事件引起的页面刷新很头痛吧! # k% H) g% I9 \ s6 e/ c, x/ n/ R ~9 ~% L ' r/ c+ ?+ c9 W5 h% b . u% P% T7 f+ c+ x0 z 2 P% l2 G9 P* b 我把解决问题的方法拿出来与大家共享,思路是事件执行完后写段脚本,让页面自动滚动到刷新页面之前的控件处,减少页面刷新 / ]" u. T2 Y, A) | 带来的不便。 9 d' r9 ^0 p+ {+ F x; }: i; G+ S: R" ?' u$ i6 I& | 比如按了一个按钮后,脚本会自动将页面自动滚动到这个按钮的位置。 & |$ B* r) Z) Y! b X! A- ~* t " a& B! q# b9 W- K6 P( c# H @; ~ e# E* b 4 S/ Q, u! Y5 r) n; i2 L) [& _% J- U " [, p0 Z: t: t# [. y7 E8 V- | 写段脚本的事情,用了一个ScriptHelper的类来搞定,这个类有个GetViewControlScript(string controlName)的方法,它返回是 5 b# |# v7 B( K1 a9 R 一段客户端的脚本,传入的参数就是这个控件的ID。 3 v" } P# Y; d4 X' b( S" Q ScriptHelper类代码: + y3 v- A* f( ~7 d2 R$ a5 k/ j /// <summary> . J3 M8 L4 ~$ q. N- X7 C /// 提供一些产生页面脚本的方法 & p+ H# r4 z; i% |* o9 ? d/ F /// </summary> 7 B; j3 v, c1 I8 j8 m/ z/ F' N F N public class ScriptHelper * k9 q/ X8 O4 D9 k" G. \/ | { 1 Q1 T1 ?: q# Q: k/ W; W 9 G3 w8 A. X& h) c \( Q- }  /// <summary> - f' ^, c( G0 q `7 N9 A  /// 获取客户端查看控件的脚本 " @, H7 M u) d1 E: u/ H7 \/ `  /// </summary> ) ~" Q$ Q9 A" S! f' R' j  /// <param name="controlName"></param> 7 x: o. I) r' g  /// <returns>脚本代码</returns> 0 g, s% n d: Y e# H/ H( f0 s  public static string GetViewControlScript(string controlName) |( j- l) `7 x3 a1 D& V) Z  { / V% Y: k7 O: _; n d2 {$ }7 O/ K7 h; d& n7 n* F! |   //创建客户端函数ViewObj - N/ q. ]4 T0 f3 I9 N   string script = "\n"; ( x+ \0 M# ~% h0 F h   script += "<script language=\"javascript\">\n"; / s+ s$ X2 \8 N" D2 ?3 ?   script += "function ViewObj(objName)\n"; ( R g) b& Y0 T: i g   script += "{\n"; 8 L0 l' B' J5 @' ]$ M& p- R   script += "var obj = document.all.item(objName);\n"; 8 l$ z( \* m; G4 H; [7 l   script += "if (obj != null)\n"; 1 J6 _! y1 T& o: T7 v3 [$ [   script += "{\n"; : m6 q# J O. J0 K- |" }   script += "\tobj.scrollIntoView();\n"; ! ^# A1 E; ~# @: U- `7 y, t9 i   script += "\tobj.focus();\n"; : p4 Q7 [* P4 q/ z) d* V   script += "}\n"; . w! e% x4 n! u6 m( a, Z   script += "}\n"; 3 Q3 _6 K/ n4 z0 I. N8 e % U! Q" [# n1 S //创建客户端函数ToDo 0 a; ~- Q0 p6 ?6 j$ \   script += "function ToDo()"; & A: A) k% k5 ^1 ~4 G; V9 n! J   script += "{\n"; " I$ d, R" N/ r9 X y$ ~5 g   script += string.Format("setTimeout(\"ViewObj('{0}')\",1000);\n", controlName); 7 L' e r/ M/ h   script += "}\n"; 8 O: z4 Q: J2 V9 ]9 k2 N$ j - A( b4 P _4 L   script += "window.onload = ToDo;\n"; ! n7 I9 {; r+ ^5 f2 G   script += "</script>\n"; & Q* B8 `: ^% G/ W F" g ( _3 \' q/ B4 v: U. e   return script; : y0 q* |% m C; z9 w+ {& s8 X! o  } ! g$ e, b; F" J: j3 y 8 n7 e$ V" P* E* r4 @' X9 o- j5 f+ c; [ } ) @# v; t5 x2 r" U 5 c; U2 L+ ]2 e 使用示例: ' ?5 M9 b2 O9 I5 R6 | 5 A3 c6 U3 Q2 e. M 为了方便输入脚本,我在页面上放了个Label:lblScript,并把lblScript的EnableViewState属性和Visible属性设成False。 : Y* r& z' i2 x F% T& U * f- \0 j; E( x z+ O8 B6 } 然后在lblScrpt的Click事件的操作代码后添加输入脚本的代码,如下所示: ( u# U, f! m# H! { private void btnSave_Click(object sender, System.EventArgs e) " J/ {. `. t; Y) w: \3 c { * Z! h! x) f+ _& {( u project.UpdateProjectInfo(ds); 7 w; R* s( y2 y" y7 a4 F( [ lblScript.Text = ScriptHelper.GetViewControlScript("btnSave"); + u3 U3 w: o( i7 t* O } ; {& n; v0 V4 a8 c% G $ Q) d( |5 r/ P( Q1 s1 ^2 n/ |* J 在点击btnSave按钮后,页面会自动滚动到btnSave的位置,减少了页面刷新带来的不便。 0 L u9 o( T6 }+ I! X :+ * M8 S( B) J1 N9 L1 T0 O5 O或者:1 k5 v1 q$ [& Z( m# g" H o8 R4 J% f , g0 F7 n' p0 v* V7 s: O( I% R在page_load()中增加判断 . u$ Q( H( |6 G9 |+ S: Z2 Y/ Z6 u if(!Page.IsPoastBack) & \( f( J4 c G* m# a* l { 8 _* R( w: @2 C7 p3 k1 q3 \: A, d //初始化页面内容; 4 n" b, |) N) C6 x M3 V$ E }
遨海湾-心灵的港湾 www.aosea.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 入住遨海湾

本版积分规则

网站解决方案专享优惠-3折上云

QQ|手机版|小黑屋|遨海湾超级社区

GMT+8, 2024-11-23 17:43

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表