每個(gè)開發(fā)人員面對(duì)的困難是預(yù)測(cè)用戶能夠或是將要做什么--這對(duì)于網(wǎng)絡(luò)開發(fā)人員來說就更為困 難,因?yàn)樗念A(yù)測(cè)必須考慮到Web
的多樣性和缺乏真正的session控制機(jī)制。如果你已經(jīng)創(chuàng)建過一個(gè)使用表單的ASP應(yīng)用程序,也許你已經(jīng)遇到過一些奇怪的問題,如數(shù)據(jù)傳輸兩次,接收數(shù)據(jù)不完整,或者用戶報(bào)告表單顯示不正確。盡管你也插入了確認(rèn)數(shù)據(jù)所需的所有客戶機(jī)端和
服務(wù)器端的腳本,表單仍然會(huì)發(fā)生許多異常情況。這些異常情況與意外用戶行為或?yàn)g覽器書簽的誤使用有關(guān)。本文將集中解決一些容易引起表單問題的典型情況:用戶意外地重復(fù)發(fā)送數(shù)據(jù),在多步驟表單中直接使用中間表單。
數(shù)據(jù)復(fù)制
通過表單重復(fù)發(fā)送數(shù)據(jù)是一個(gè)常見的情況,但是它會(huì)帶來問題。在理想的情況下,用戶在一個(gè) Web
站點(diǎn)遇到一個(gè)表單,用正確的數(shù)據(jù)類型填充它,將它提交給處理數(shù)據(jù)的服務(wù)器,然后作為回應(yīng)發(fā)送給用戶一個(gè)確認(rèn)頁,這時(shí)用戶就可以再去做別的。如果用戶重新訪問前面那一頁,使用back
按鈕,然后無意中再將數(shù)據(jù)發(fā)送一次,那將會(huì)出現(xiàn)什么情形呢?如果你沒有預(yù)料到這一場(chǎng)景并且有所準(zhǔn)備,數(shù)據(jù)就將被重新傳送給服務(wù)器并且再處理一次。試想這些數(shù)據(jù)是一份訂單或旅館預(yù)約,那將會(huì)帶來很不愉快的結(jié)果。
終止重復(fù)數(shù)據(jù)傳輸
為了避免那些錯(cuò)誤地重復(fù)發(fā)送給服務(wù)器的數(shù)據(jù),可以在服務(wù)器側(cè)進(jìn)行一些校驗(yàn),來確定用戶能
意識(shí)到他們正在發(fā)送數(shù)據(jù)。這里使用的例子包含一個(gè)有單一文本框的簡(jiǎn)單表單,表單接收一些文本,然后將其發(fā)送到一個(gè)顯示它們的ASP頁。
為確保用戶不將同樣的信息發(fā)送兩次,需要指示數(shù)據(jù)已經(jīng)被服務(wù)器接收到。存儲(chǔ)這些信息的最好的地方是一個(gè)session變量。定義一個(gè)session變量Session("submitted")
,當(dāng)用戶第一次到達(dá)這個(gè)表單時(shí)將它初始化為False,在用戶進(jìn)行最初的數(shù)據(jù)傳輸時(shí)將它設(shè)置為true
。如果用戶在當(dāng)前的session期間重新訪問這個(gè)表單,將出現(xiàn)相關(guān)重復(fù)提交信息。
所以用戶只能是在有意的情況下向服務(wù)器重復(fù)發(fā)送數(shù)據(jù)?,F(xiàn)在來看看執(zhí)行這一校驗(yàn)的代碼。建立表單并且校驗(yàn)已發(fā)送數(shù)據(jù)的ASP頁(在下載處為form.asp)有以下結(jié)構(gòu):
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
〈 % If
Session("submitted") Then % 〉
〈 !-- Code showing the warning message -- 〉
... 〈 % Else % 〉
〈 !-- Code showing the form -- 〉
... 〈 % End If % 〉
〈 /BODY 〉
〈 /HTML 〉
表單和警告信息都是從同一個(gè)ASP頁創(chuàng)建的。表單包括標(biāo)準(zhǔn)的HTML代碼,引用ManageForm.asp頁作為它的ACTION 屬性:
〈 FORM METHOD="post" ACTION="ManageForm.asp" 〉
Send me some data:
〈 INPUT TYPE="text" NAME="data" 〉
〈 P 〉
〈 INPUT TYPE="submit"
VALUE="Submit" 〉
〈 INPUT TYPE="reset" VALUE="Cancel" 〉
〈 /FORM 〉
ManageForm.asp 頁接收用戶發(fā)送的文本,顯示它并將session 變量submitted設(shè)置為True:
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
You have sent the following
information:
〈 P 〉
〈 %= Request("data") % 〉
〈 % Session("submitted")
= True % 〉
〈 /BODY 〉
〈 /HTML 〉
所以當(dāng)用戶又回到這個(gè)表單時(shí),測(cè)試session
變量submitted,當(dāng)它的值為True時(shí),發(fā)送給用 戶的是警告信息而不是輸入表單。這個(gè)警告信息是用HTML和客戶機(jī)側(cè)的Javascript代碼組合編寫的:
〈 script 〉
function SendAnswer(answer) {
document.AnswerForm.answer.value = answer document.AnswerForm.submit() }
〈
/script 〉
You have already submitted some information to this Web site.
〈 BR 〉 Do you want submit again?
〈 P 〉
〈 FORM NAME="AnswerForm"
METHOD="post" ACTION="CheckAnswer.asp" 〉
〈 INPUT TYPE="button" VALUE="Yes"
onClick="SendAnswer('Y')" 〉
〈 INPUT TYPE="button" VALUE="No"
onClick="SendAnswer('N')" 〉
〈 INPUT TYPE="hidden" NAME="answer" VALUE="" 〉
〈 /FORM 〉
表單包含兩個(gè)按鈕((Yes 和 No) 以及一個(gè)隱含控制域(answer) ,在其中保存用戶所選擇的值: Y 或
N。這個(gè)值由Javascript 函數(shù)SendAnswer() 設(shè)置,這個(gè)函數(shù)還將它發(fā)送給CheckAnswer.asp
頁以執(zhí)行正確的重定向。如果用戶選擇了No按鈕,CheckAnswer.asp 檢驗(yàn)隱含控制的值,并將其重定向到一個(gè)普通 welcome
頁,反之就將session 變量submitted設(shè)置為False 并再次將其重定向到表單頁。
〈 % If Request("answer") =
"Y" Then Session("submitted") = False Response.Redirect "form.asp" Else
Response.Redirect "welcome.htm" End If % 〉
控制瀏覽器緩沖器
如果你已經(jīng)實(shí)施了以上方法,你會(huì)發(fā)現(xiàn),只有當(dāng)你在瀏覽器的地址文本框內(nèi)鍵入U(xiǎn)RL來回到這個(gè)
表單時(shí),此方法才奏效。它依靠的是瀏覽器的緩沖器機(jī)制。如果你使用back按鈕來返回頁,瀏覽器就檢測(cè)它的緩沖器來找到該頁的副本。它將使用緩存的頁而不是向服務(wù)器發(fā)出請(qǐng)求。所以服務(wù)器就
不能在session
變量submitted上進(jìn)行校驗(yàn)。為了避免這種情況,就要抑制瀏覽器的頁緩沖器。這通過在表單頁中處理Response對(duì)象來實(shí)現(xiàn)。取消頁緩沖器有多種方法。所有這些方法都要依靠HTTP頭文件中到瀏覽器的地址指示。但是所有瀏覽器對(duì)服務(wù)器發(fā)送的指示反應(yīng)不同,所以說最好能多發(fā)送一些指示來為更多的瀏覽器抑制緩沖器,按以下代碼所示:
〈 % Response.AddHeader "cache-control", "private" Response.AddHeader
"pragma", "no-cache" Response.ExpiresAbsolute = #January 1, 1990 00:00:01#
Response.Expires=0 % 〉
以上代碼的頭兩行使用Response 對(duì)象的AddHeader
方法來將頭信息附加到HTTP頭文件中。 Expires 和 ExpiresAbsolute
屬性用瀏覽器緩沖器中頁的持續(xù)時(shí)間信息來標(biāo)記當(dāng)前頁。在表單頁中,這些行必須要插入在所有代碼之前,因?yàn)樗齻兯玫男畔⒎胖迷贖TTP頭文件中,在所有輸出之前發(fā)送給瀏覽器。
多步驟表單
如果一個(gè)表單需要許多數(shù)據(jù),那么最好將你要求的數(shù)據(jù)劃分成多個(gè)小表單,這樣使用戶可以一步一步地填充表單,而不用等待表單加載許多HTML控制。另外還有一些情況,表單中的某些控制不完全必要,并且可以用已經(jīng)提交的數(shù)據(jù)逐行填充。使用多步驟表單允許顯示倚賴于用戶以前答案的定制表單。如果用戶在瀏覽器中將一個(gè)中間表單設(shè)置為書簽的話就會(huì)產(chǎn)生問題。在隨后的一個(gè)session中,用戶就試圖直接到達(dá)這個(gè)表單并提交數(shù)據(jù),這些數(shù)據(jù)已經(jīng)在上下文范圍之外,因?yàn)楸緛響?yīng)該在前面
表單收集的session 數(shù)據(jù)丟失了。
避免使用中間步驟表單
為了避免這些問題,可以存儲(chǔ)當(dāng)前數(shù)據(jù)收集的狀態(tài)。這個(gè)狀態(tài)可以用一個(gè)session 變量來代表
來記錄是否執(zhí)行了一個(gè)特定的步驟---用戶是否填充了給出的表單。在一個(gè)多步驟表單中,每個(gè)表單都可以通過一個(gè)Boolean型的session變量來實(shí)現(xiàn)。如果有關(guān)表單沒有被處理,變量就為False
,反之就是True。下載部分的第二個(gè)例子顯示一個(gè)兩步驟表單:第一個(gè)表單要求用戶名,第二個(gè)表單顯示一個(gè)組合框,它的列表項(xiàng)要依賴第一個(gè)表單所提供的用戶名。第一個(gè)表單與一個(gè)session變量requested1相關(guān)聯(lián),你可以想象出來,第二個(gè)表單與變量requested2相關(guān)聯(lián)。當(dāng)用戶要求第一個(gè)表單(form1.asp)
時(shí),session變量 requested1 被設(shè)置為 True :
〈 FORM METHOD="post"
ACTION="form2.asp" 〉
Your name: 〈 INPUT TYPE="text" NAME="name" 〉
〈 P 〉
〈 INPUT TYPE="submit" VALUE="Submit" 〉
〈 INPUT TYPE="reset"
VALUE="Cancel" 〉
〈 /FORM 〉
〈 % Session("requested1") = True % 〉
這個(gè)值將由下一個(gè)表單( form2.asp ) 來校驗(yàn),以確定是否滿足了要求。事實(shí)上當(dāng)用戶要求第二個(gè)表單時(shí)校驗(yàn)requested1
變量。如果為True,就向?yàn)g覽器發(fā)送第二個(gè)表單并將requested2變量設(shè)置為True。如果為False
就意味著用戶想要直接使用第二個(gè)表單,于是瀏覽器就重定向到第一個(gè)表單。以下代碼是第二個(gè)表單的ASP頁:
〈 % If
Session("requested1") Then % 〉
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈
BODY 〉
〈 !-- Code for the second form -- 〉
... 〈 % Session("requested2")
= True Else Response.Redirect "form1.asp" End If % 〉
〈 /BODY 〉
〈 /HTML 〉
要注意對(duì)requested1 的校驗(yàn)必須要在〈 HTML
〉記錄之前進(jìn)行,這樣就允許可能的重定向。實(shí)際上,重定向是對(duì)瀏覽器的指示,它出現(xiàn)在HTTP頭文件中,在所有的HTML代碼之前。
結(jié)論
本文所示范的兩種技巧允許ASP開發(fā)人員對(duì)某些奇怪的情況有所控制,這些奇怪情況會(huì)造成用戶 通過一個(gè)Web
表單向服務(wù)器重復(fù)發(fā)送數(shù)據(jù)。每個(gè)技巧解決一個(gè)特定問題,所以最好將兩者混合使用,在ASP應(yīng)用程序每個(gè)表單中管理兩個(gè)session 變量。[@more@]
標(biāo)題名稱:高級(jí)表單驗(yàn)證-針對(duì)多次提交表單(轉(zhuǎn))
文章地址:http://aaarwkj.com/article4/gpejoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、網(wǎng)站維護(hù)、用戶體驗(yàn)、定制網(wǎng)站、搜索引擎優(yōu)化、虛擬主機(jī)
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)