【移動(dòng)應(yīng)用開發(fā)技術(shù)】web中如何處理重復(fù)提交、重復(fù)刷新、防止后退的問題_第1頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】web中如何處理重復(fù)提交、重復(fù)刷新、防止后退的問題_第2頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】web中如何處理重復(fù)提交、重復(fù)刷新、防止后退的問題_第3頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】web中如何處理重復(fù)提交、重復(fù)刷新、防止后退的問題_第4頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】web中如何處理重復(fù)提交、重復(fù)刷新、防止后退的問題_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】web中如何處理重復(fù)提交、重復(fù)刷新、防止后退的問題

2。防止用戶后退這里的方法是千姿百態(tài),有的是更改瀏覽器的歷史紀(jì)錄的,比如使用window.history.forward()方法;有的是“用新頁面的URL替換當(dāng)前的歷史紀(jì)錄,這樣瀏覽歷史記錄中就只有一個(gè)頁面,后退按鈕永遠(yuǎn)不會(huì)變?yōu)榭捎??!北热缡褂胘avascript:location.replace(this.href);event.returnValue=false;2.服務(wù)器端的處理(這里只說Struts框架的處理)利用同步令牌(Token)機(jī)制來解決Web應(yīng)用中重復(fù)提交的問題,Struts也給出了一個(gè)參考實(shí)現(xiàn)。基本原理:服務(wù)器端在處理到達(dá)的請求之前,會(huì)將請求中包含的令牌值與保存在當(dāng)前用戶會(huì)話中的令牌值進(jìn)行比較,看是否匹配。在處理完該請求后,且在答復(fù)發(fā)送給客戶端之前,將會(huì)產(chǎn)生一個(gè)新的令牌,該令牌除傳給客戶端以外,也會(huì)將用戶會(huì)話中保存的舊的令牌進(jìn)行替換。這樣如果用戶回退到剛才的提交頁面并再次提交的話,客戶端傳過來的令牌就和服務(wù)器端的令牌不一致,從而有效地防止了重復(fù)提交的發(fā)生。if(isTokenValid(request,true)){//yourcodeherereturnmapping.findForward("success");}else{saveToken(request);returnmapping.findForward("submitagain");}Struts根據(jù)用戶會(huì)話ID和當(dāng)前系統(tǒng)時(shí)間來生成一個(gè)唯一(對于每個(gè)會(huì)話)令牌的,具體實(shí)現(xiàn)可以參考TokenProcessor類中的generateToken()方法。1.//驗(yàn)證事務(wù)控制令牌,<html:form>會(huì)自動(dòng)根據(jù)session中標(biāo)識(shí)生成一個(gè)隱含input代表令牌,防止兩次提交2.在action中://<inputtype="hidden"name="org.apache.struts.taglib.html.TOKEN"http://value="6aa35341f25184fd996c4c918255c3ae">if(!isTokenValid(request))errors.add(ActionErrors.GLOBAL_ERROR,newActionError("error.transaction.token"));resetToken(request);//刪除session中的令牌3.action有這樣的一個(gè)方法生成令牌protectedStringgenerateToken(HttpServletRequestrequest){HttpSessionsession=request.getSession_r();try{byteid[]=session.getId_r().getBytes_r();bytenow[]=newLong(System.currentTimeMillis()).toString().getBytes_r();MessageDigestmd=MessageDigest.getInstance_r("MD5");md.update(id);md.update(now);return(toHex(md.digest()));}catch(IllegalStateExceptione){return(null);}catch(NoSuchAlgorithmExceptione){return(null);}}總結(jié)對于重復(fù)提交、重復(fù)刷新、防止后退等等都是屬于系統(tǒng)為避免重復(fù)記錄而需要解決的問題,在客戶端去處理需要針對每一種的可能提出相應(yīng)的解決方案,然而在服務(wù)器端看來只不過是對于數(shù)據(jù)真實(shí)性的檢驗(yàn)問題,基于令牌的處理就是一勞永逸的方法。同時(shí)我們也看到,從不同的角度去看待問題,其解決的方法也是不同的??蛻舳烁非蟮氖怯脩舻牟僮鳎?wù)端則將注意力放在了數(shù)據(jù)的處理上,所以在某個(gè)對于服務(wù)器端看似容易的問題上,用客戶端來解決卻麻煩了很多!反之依然。所以在某些問題的處理上我們需要綜合考慮和平衡,是用客戶端來解決?還是用服務(wù)器端來處理?

網(wǎng)頁防刷新重復(fù)提交、防后退解決方法提交后禁用提交按鈕(大部分人都是這樣做的)如果客戶提交后,按F5刷新怎么辦?使用Session在提交的頁面也就是數(shù)據(jù)庫處理之前:ifsession("ok")=truethenresponse.write"錯(cuò)誤,正在提交"response.endendif數(shù)據(jù)處理完后,修改session("ok")=false。數(shù)據(jù)處理成功馬上Redirect到另外一個(gè)頁面操作后刷新的確是個(gè)問題,你可以使用跳轉(zhuǎn)頁面、關(guān)閉本頁面,如果是有參數(shù)據(jù)條件來控制的,那就應(yīng)該好做了,可以直接修改window.location的值,把參數(shù)全部改掉,這樣就差不多了。缺點(diǎn):簡單地運(yùn)用Response.Redirect將不再有效,因?yàn)橛脩魪囊粋€(gè)頁面轉(zhuǎn)到另一個(gè)頁面,我們都必須用客戶端代碼清除location.history。注意,這種方法清除的是最后一個(gè)訪問歷史記錄,而不是全部的訪問記錄。點(diǎn)擊后退按鈕,再點(diǎn)擊后退按鈕,你可以看到這時(shí)打開的是本頁面之前的頁面!(當(dāng)然,這是在你的客戶端啟用了JavaScript功能的條件下。)如果客戶按后退,怎么辦?防止網(wǎng)頁后退--禁止緩存我們在進(jìn)行數(shù)據(jù)庫添加操作的時(shí)候,如果允許后退,而正巧有刷新了頁面,就會(huì)再次執(zhí)行添加操作,無疑這不是我們需要的,像一般網(wǎng)上很多禁止緩存的代碼,有時(shí)并不可靠,這時(shí)你只要在操作的頁面加上就可以了,在網(wǎng)頁的里指定要定向的新頁,再點(diǎn)后退,看是不是不會(huì)再退到剛才的操作頁面了,實(shí)際上已經(jīng)把這個(gè)歷史給刪除了ASP:Response.Buffer=TrueResponse.ExpiresAbsolute=Now()-1Response.Expires=0Response.CacheControl="no-cache"ASP.NET:Response.Buffer=true;Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);Response.Expires=0;Response.CacheControl="no-cache";究竟怎樣才能"禁用"瀏覽器的后退按鈕?或者“怎樣才能防止用戶點(diǎn)擊后退按鈕返回以前瀏覽過的頁面?”遺憾的是,我們無法禁用瀏覽器的后退按鈕。防止網(wǎng)頁后退--新開窗口用window.open彈出表單頁面,點(diǎn)提交后關(guān)閉該頁;處理提交的ASP頁也是用彈出,設(shè)定表單的target,點(diǎn)提交時(shí)window.open("XXX.asp","_blank"),然后用JS來提交表單,完成后window.close();簡單的說,就是提交表單的時(shí)候彈出新窗口,關(guān)閉本窗口。對于window.open()打開的窗口怎么后退?能后退到哪里去?呵呵,羅嗦了一堆廢話,知道怎么處理了么?混合運(yùn)用客戶端腳本和服務(wù)器端腳本。

jsp重復(fù)提交問題看了網(wǎng)上的,有幾種方法:1在你的表單頁里HEAD區(qū)加入這段代碼:<METAHTTP-EQUIV="pragma"CONTENT="no-cache"><METAHTTP-EQUIV="Cache-Control"CONTENT="no-cache,must-revalidate"><METAHTTP-EQUIV="expires"CONTENT="Wed,26Feb199708:21:57GMT">2生成一個(gè)令牌保存在用戶session中,在form中加一個(gè)hidden域,顯示該令牌的值,form提交后重新生成一個(gè)新的令牌,將用戶提交的令牌和session中的令牌比較,如相同則是重復(fù)提交3在你的服務(wù)器端控件的代碼中使用Response.Redirect("selfPage")語句。但是大多的數(shù)都不使用這種方法。方法還有很多。。。4<inputtype="button"value="提交"onclick="this.disabled=true;this.form.submit()">5在JSP頁面的FORM表單中添加一個(gè)hidden域<inputtype="hidden"name="url"value=<%=request.getRequestURL_r()%>>在你的serverlet中添加如下語句Stringurl=request.getParameter_r("url");response.sendRedirect(url);我一般都是采用這樣的方法返回JSP頁面的,不太明白你說的重復(fù)刷新是什么概念6ajax無刷新提交7Web開發(fā)中防止瀏覽器的刷新鍵引起系統(tǒng)操作重復(fù)提交怎么解決呢?重定向可以解決頁面刷新帶來的數(shù)據(jù)的重復(fù)提交的問題,我們自然可以利用重定向的方式來解決這個(gè)問題。但是struts的action里面mapping.findword();跳轉(zhuǎn)的話,默認(rèn)的是在工程文件夾里面找要跳轉(zhuǎn)的頁面。這種情況,怎么解決呢?修改struts-config.xml文件,在action里面有一個(gè)redirect重新定向的屬性,struts中默認(rèn)的是false,添加這個(gè)屬性,改成true,在forword中寫上要跳轉(zhuǎn)頁面的絕對或者相對地址就行了修改如下:<action-mappings><actionattribute="newsActionForm"name="newsActionForm"input="/addnews.jsp"path="/newsAction"parameter="method"scope="request"type="com.yongtree.news.action.NewsAction"><forwardname="list"path="/listnews.jsp"redirect="true"></forward><forwardname="error"path="/addnews.jsp"></forward></action></action-mappings>瀏覽器相關(guān)難處理的問題瀏覽器的后退按鈕使得我們能夠方便地返回以前訪問過的頁面,它無疑非常有用。但有時(shí)候我們不得不關(guān)閉這個(gè)功能,以防止用戶打亂預(yù)定的頁面訪問次序。本文介紹網(wǎng)絡(luò)上可找到的各種禁用瀏覽器后退按鈕方案,分析它們各自的優(yōu)缺點(diǎn)和適用場合。一、概述曾經(jīng)有許多人問起,“怎樣才能‘禁用’瀏覽器的后退按鈕?”,或者“怎樣才能防止用戶點(diǎn)擊后退按鈕返回以前瀏覽過的頁面?”在ASP論壇上,這個(gè)問題也是問得最多的問題之一。遺憾的是,答案非常簡單:我們無法禁用瀏覽器的后退按鈕。起先我對于居然有人想要禁用瀏覽器的后退按鈕感到不可思議。后來,看到竟然有那么多的人想要禁用這個(gè)后退按鈕,我也就釋然(想要禁用的只有后退按鈕,不包括瀏覽器的前進(jìn)按鈕)。因?yàn)樵谀J(rèn)情況下,用戶提交表單之后可以通過后退按鈕返回表單頁面(而不是使用“編輯”按鈕?。缓笤俅尉庉嫴⑻峤槐韱蜗驍?shù)據(jù)庫插入新的記錄。這是我們不愿看到的。因此我就決定要找出避免出現(xiàn)這種情況的方法。我訪問了許多網(wǎng)站,參考了這些網(wǎng)站所介紹的各種實(shí)現(xiàn)方法。如果你經(jīng)常訪問ASP編程網(wǎng)站,本文所介紹的部分內(nèi)容你可能已經(jīng)見到過。本文的任務(wù)是把各種可能的方法都介紹給大家,然后找出最好的方法!二、禁止緩存在我找到的許多方案中,其中有一種建議禁止頁面緩存。具體是使用服務(wù)器端腳本,如下所示:<%Response.Buffer=TrueResponse.ExpiresAbsolute=Now()-1Response.Expires=0Response.CacheControl="no-cache"%>這種方法非常有效!它強(qiáng)制瀏覽器重新訪問服務(wù)器下載頁面,而不是從緩存讀取頁面。使用這種方法時(shí),編程者的主要任務(wù)是創(chuàng)建一個(gè)會(huì)話級(jí)的變量,通過這個(gè)變量確定用戶是否仍舊可以查看那個(gè)不適合通過后退按鈕訪問的頁面。由于瀏覽器不再緩存這個(gè)頁面,當(dāng)用戶點(diǎn)擊后退按鈕時(shí)瀏覽器將重新下載該頁面,此時(shí)程序就可以檢查那個(gè)會(huì)話變量,看看是否應(yīng)該允許用戶打開這個(gè)頁面。例如,假設(shè)我們有如下表單:<%Response.Buffer=TrueResponse.ExpiresAbsolute=Now()-1Response.Expires=0Response.CacheControl="no-cache"IfLen(Session("FirstTimeToPage"))>0then&single;用戶已經(jīng)訪問過當(dāng)前頁面,現(xiàn)在是再次返回訪問。&single;清除會(huì)話變量,將用戶重定向到登錄頁面。Session("FirstTimeToPage")=""Response.Redirect"/Bar.asp"Response.EndEndIf&single;如果程序運(yùn)行到這里,說明用戶能夠查看當(dāng)前頁面&single;以下開始創(chuàng)建表單%><formmethod=postaction="SomePage.asp"><inputtype=submit></form>我們借助會(huì)話變量FirstTimeToPage檢查用戶是否是第一次訪問當(dāng)前頁面。如果不是第一次(即Session("FirstTimeToPage")包含某個(gè)值),那么我們就清除會(huì)話變量的值,然后把用戶重新定向到一個(gè)開始頁面。這樣,當(dāng)表單提交時(shí)(此時(shí)SompePage.asp被打開),我們必須賦予FirstTimeToPage一個(gè)值。即,在SomePage.asp中我們需要加上下面的代碼:Session("FirstTimeToPage")="NO"這樣,已經(jīng)打開SomePage.asp的用戶如果點(diǎn)擊后退按鈕,瀏覽器將重新請求服務(wù)器下載頁面,服務(wù)器檢查到Session("FirstTimeToPage")包含了一個(gè)值,于是就清除Session("FirstTimeToPage"),并把用戶重定向到其他頁面。當(dāng)然,所有這一切都需要用戶啟用了Cookie,否則會(huì)話變量將是無效的。(有關(guān)該問題的更多說明,請參見Forsessionariablestowork,musttheWebvisitorhavecookiesenabled?)另外,我們也可以用客戶端代碼使瀏覽器不再緩存Web頁面:<html><head><metahttp-equiv="Expires"CONTENT="0"><metahttp-equiv="Cache-Control"CONTENT="no-cache"><metahttp-equiv="Pragma"CONTENT="no-cache"></head>如果使用上面的方法強(qiáng)制瀏覽器不再緩存Web頁面,必須注意以下幾點(diǎn):只有在使用安全連接時(shí)“Pragma:no-cache”才防止瀏覽器緩存頁面。對于不受安全保護(hù)的頁面,“Pragma:no-cache”被視為與“Expires:-1”相同,此時(shí)瀏覽器仍舊緩存頁面,但把頁面標(biāo)記為立即過期。在IE4或5中,“Cache-Control”METAHTTP-EQUIV標(biāo)記將被忽略,不起作用。在實(shí)際應(yīng)用中我們可以加上所有這些代碼。然而,由于這種方法不能適用于所有的瀏覽器,所以是不推薦使用的。但如果是在Intranet環(huán)境下,管理員可以控制用戶使用哪種瀏覽器,我想還是有人會(huì)使用這種方法。三、其他方法接下來我們要討論的方法以后退按鈕本身為中心,而不是瀏覽器緩存。這兒有一篇文章RewiringtheBackButton很值得參考。不過我注意到,如果使用這種方法,雖然用戶點(diǎn)擊一下后退按鈕時(shí)他不會(huì)看到以前輸入數(shù)據(jù)的頁面,但只要點(diǎn)擊兩次就可以,這可不是我們希望的效果,因?yàn)楹芏鄷r(shí)候,固執(zhí)的用戶總是能夠找到繞過預(yù)防措施的辦法。另外一種禁用后退按鈕的辦法是用客戶端JavaScript打開一個(gè)沒有工具條的窗口,這使得用戶很難返回前一頁面,但不是不可能。一種更安全但相當(dāng)惱人的方法是,當(dāng)表單提交時(shí)打開一個(gè)新的窗口,與此同時(shí)關(guān)閉表單所在的窗口。但我覺得這種方法不值得認(rèn)真考慮,因?yàn)槲覀兛偛荒茏層脩裘刻峤灰粋€(gè)表單就打開一個(gè)新窗口。那么,在那個(gè)我們不想讓用戶返回的頁面是否也可以加入JavaScript代碼呢?在這個(gè)頁面中加入的JavaScript代碼可用來產(chǎn)生點(diǎn)擊前進(jìn)按鈕的效果,這樣也就抵消了用戶點(diǎn)擊后退按鈕所產(chǎn)生的動(dòng)作。用于實(shí)現(xiàn)該功能的JavaScript代碼如下所示:<scriptlanguage="JavaScript"><!--javascript:window.history.forward(1);//--></script>同樣地,這種方法雖然有效,但距離“最好的方法”還差得很遠(yuǎn)。后來我又看到有人建議用location.replace從一個(gè)頁面轉(zhuǎn)到另一個(gè)頁面。這種方法的原理是,用新頁面的URL替換當(dāng)前的歷史紀(jì)錄,這樣瀏覽歷史記錄中就只有一個(gè)頁面,后退按鈕永遠(yuǎn)不會(huì)變?yōu)榭捎?。我想這可能正是許多人所尋求的方法,但這種方法仍舊不是任何情況下的最好方法。使用這種方法的實(shí)例如下所示:<AHREF="PageName.htm"onclick="javascript:location.replace(this.href);event.returnValue=false;">禁止后退到本頁面的鏈接</A>禁止后退到本頁面的鏈接!這種方法的缺點(diǎn)在于:簡單地運(yùn)用Response.Redirect將不再有效,這是因?yàn)槊看斡脩魪囊粋€(gè)頁面轉(zhuǎn)到另一個(gè)頁面,我們都必須用客戶端代碼清除location.history。另外還要注意,這種方法清除的是最后一個(gè)訪問歷史記錄,而不是全部的訪問記錄。點(diǎn)擊上面的鏈接,你將打開一個(gè)簡單的HTML頁面。再點(diǎn)擊后退按鈕,你可以看到這時(shí)打開的不是本頁面,而是本頁面之前的頁面?。ó?dāng)然,你必須在瀏覽器中啟用了客戶端JavaScript代碼。)經(jīng)過一番仔細(xì)的尋尋覓覓之后,我發(fā)現(xiàn)仍舊無法找出真正能夠完全禁用瀏覽器后退按鈕的辦法。所有這里介紹的方法都能夠在不同程度上、以不同的方式禁止用戶返回前一頁面,但它們都有各自的局限。由于不存在能夠完全禁用后退按鈕的方法,所以最好的方案應(yīng)該是:混合運(yùn)用客戶端腳本和服務(wù)器端腳本。<html><head><metahttp-equiv="Expires"CONTENT="0"><metahttp-equiv="Cache-Control"CONTENT="no-cache"><metahttp-equiv="Pragma"CONTENT="

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論