每個開發人員面對的困難是預測用戶能夠或是將要做什麼
這對於網絡開發人員來說就更為困 難
因為他的預測必須考慮到Web 的多樣性和缺乏真正的session控制機制
如果你已經創建過一個使用表單的ASP應用程序
也許你已經遇到過一些奇怪的問題
如數據傳輸兩次
接收數據不完整
或者用戶報告表單顯示不正確
盡管你也插入了確認數據所需的所有客戶機端和服務器端的腳本
表單仍然會發生許多異常情況
這些異常情況與意外用戶行為或浏覽器書簽的誤使用有關
本文將集中解決一些容易引起表單問題的典型情況
用戶意外地重復發送數據
在多步驟表單中直接使用中間表單
數據復制
通過表單重復發送數據是一個常見的情況
但是它會帶來問題
在理想的情況下
用戶在一個 Web 站點遇到一個表單
用正確的數據類型填充它
將它提交給處理數據的服務器
然後作為回應發送給用戶一個確認頁
這時用戶就可以再去做別的
如果用戶重新訪問前面那一頁
使用back 按鈕
然後無意中再將數據發送一次
那將會出現什麼情形呢?如果你沒有預料到這一場景並且有所准備
數據就將被重新傳送給服務器並且再處理一次
試想這些數據是一份訂單或旅館預約
那將會帶來很不愉快的結果
終止重復數據傳輸
為了避免那些錯誤地重復發送給服務器的數據
可以在服務器側進行一些校驗
來確定用戶能 意識到他們正在發送數據
這裡使用的例子包含一個有單一文本框的簡單表單
表單接收一些文本
然後將其發送到一個顯示它們的ASP頁
為確保用戶不將同樣的信息發送兩次
需要指示數據已經被服務器接收到
存儲這些信息的最好的地方是一個session變量
定義一個session變量Session(
submitted
)
當用戶第一次到達這個表單時將它初始化為False
在用戶進行最初的數據傳輸時將它設置為true
如果用戶在當前的session期間重新訪問這個表單
將出現相關重復提交信息
所以用戶只能是在有意的情況下向服務器重復發送數據
現在來看看執行這一校驗的代碼
建立表單並且校驗已發送數據的ASP頁(在下載處為form
asp)有以下結構
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
〈 % If Session(
submitted
) Then % 〉
〈 !
Code showing the warning message
〉
〈 % Else % 〉
〈 !
Code showing the form
〉
〈 % End If % 〉
〈 /BODY 〉
〈 /HTML 〉
表單和警告信息都是從同一個ASP頁創建的
表單包括標准的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 頁接收用戶發送的文本
顯示它並將session 變量submitted設置為True:
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
You have sent the following information:
〈 P 〉
〈 %= Request(
data
) % 〉
〈 % Session(
submitted
) = True % 〉
〈 /BODY 〉
〈 /HTML 〉
所以當用戶又回到這個表單時
測試session 變量submitted
當它的值為True時
發送給用 戶的是警告信息而不是輸入表單
這個警告信息是用HTML和客戶機側的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 〉
表單包含兩個按鈕((Yes 和 No) 以及一個隱含控制域(answer)
在其中保存用戶所選擇的值
Y 或 N
這個值由JavaScript 函數SendAnswer() 設置
這個函數還將它發送給CheckAnswer
asp 頁以執行正確的重定向
如果用戶選擇了No按鈕
CheckAnswer
asp 檢驗隱含控制的值
並將其重定向到一個普通 welcome 頁
反之就將session 變量submitted設置為False 並再次將其重定向到表單頁
〈 % If Request(
answer
) =
Y
Then Session(
submitted
) = False Response
Redirect
form
asp
Else Response
Redirect
End If % 〉
控制浏覽器緩沖器
如果你已經實施了以上方法
你會發現
只有當你在浏覽器的地址文本框內鍵入URL來回到這個 表單時
此方法才奏效
它依靠的是浏覽器的緩沖器機制
如果你使用back按鈕來返回頁
浏覽器就檢測它的緩沖器來找到該頁的副本
它將使用緩存的頁而不是向服務器發出請求
所以服務器就 不能在session 變量submitted上進行校驗
為了避免這種情況
就要抑制浏覽器的頁緩沖器
這通過在表單頁中處理Response對象來實現
取消頁緩沖器有多種方法
所有這些方法都要依靠HTTP頭文件中到浏覽器的地址指示
但是所有浏覽器對服務器發送的指示反應不同
所以說最好能多發送一些指示來為更多的浏覽器抑制緩沖器
按以下代碼所示
〈 % Response
AddHeader
cache
control
private
Response
AddHeader
pragma
no
cache
Response
ExpiresAbsolute = #January
:
:
# Response
Expires=
% 〉
以上代碼的頭兩行使用Response 對象的AddHeader 方法來將頭信息附加到HTTP頭文件中
Expires 和 ExpiresAbsolute 屬性用浏覽器緩沖器中頁的持續時間信息來標記當前頁
在表單頁中
這些行必須要插入在所有代碼之前
因為她們所引用的信息放置在HTTP頭文件中
在所有輸出之前發送給浏覽器
多步驟表單
如果一個表單需要許多數據
那麼最好將你要求的數據劃分成多個小表單
這樣使用戶可以一步一步地填充表單
而不用等待表單加載許多HTML控制
另外還有一些情況
表單中的某些控制不完全必要
並且可以用已經提交的數據逐行填充
使用多步驟表單允許顯示倚賴於用戶以前答案的定制表單
如果用戶在浏覽器中將一個中間表單設置為書簽的話就會產生問題
在隨後的一個session中
用戶就試圖直接到達這個表單並提交數據
這些數據已經在上下文范圍之外
因為本來應該在前面 表單收集的session 數據丟失了
避免使用中間步驟表單
為了避免這些問題
可以存儲當前數據收集的狀態
這個狀態可以用一個session 變量來代表 來記錄是否執行了一個特定的步驟
用戶是否填充了給出的表單
在一個多步驟表單中
每個表單都可以通過一個Boolean型的session變量來實現
如果有關表單沒有被處理
變量就為False
反之就是True
下載部分的第二個例子顯示一個兩步驟表單
第一個表單要求用戶名
第二個表單顯示一個組合框
它的列表項要依賴第一個表單所提供的用戶名
第一個表單與一個session變量requested
相關聯
你可以想象出來
第二個表單與變量requested
相關聯
當用戶要求第一個表單(form
asp) 時
session變量 requested
被設置為 True :
〈 FORM METHOD=
post
ACTION=
form
asp
〉
Your name: 〈 INPUT TYPE=
text
NAME=
name
〉
〈 P 〉
〈 INPUT TYPE=
submit
VALUE=
Submit
〉
〈 INPUT TYPE=
reset
VALUE=
Cancel
〉
〈 /FORM 〉
〈 % Session(
requested
) = True % 〉
這個值將由下一個表單( form
asp ) 來校驗
以確定是否滿足了要求
事實上當用戶要求第二個表單時校驗requested
變量
如果為True
就向浏覽器發送第二個表單並將requested
變量設置為True
如果為False 就意味著用戶想要直接使用第二個表單
於是浏覽器就重定向到第一個表單
以下代碼是第二個表單的ASP頁
〈 % If Session(
requested
) Then % 〉
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
〈 !
Code for the second form
〉
〈 % Session(
requested
) = True Else Response
Redirect
form
asp
End If % 〉
〈 /BODY 〉
〈 /HTML 〉
要注意對requested
的校驗必須要在〈 HTML 〉記錄之前進行
這樣就允許可能的重定向
實際上
重定向是對浏覽器的指示
它出現在HTTP頭文件中
在所有的HTML代碼之前
結論
本文所示范的兩種技巧允許ASP開發人員對某些奇怪的情況有所控制
這些奇怪情況會造成用戶 通過一個Web 表單向服務器重復發送數據
每個技巧解決一個特定問題
所以最好將兩者混合使用
在ASP應用程序每個表單中管理兩個session 變量
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19718.html