熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

高級表單驗證-針對多次提交表單

2013-11-15 11:50:07  來源: JSP教程 
每個開發人員面對的困難是預測用戶能夠或是將要做什麼這對於網絡開發人員來說就更為困 難因為他的預測必須考慮到Web 的多樣性和缺乏真正的session控制機制如果你已經創建過一個使用表單的ASP應用程序也許你已經遇到過一些奇怪的問題如數據傳輸兩次接收數據不完整或者用戶報告表單顯示不正確盡管你也插入了確認數據所需的所有客戶機端和服務器端的腳本表單仍然會發生許多異常情況這些異常情況與意外用戶行為或浏覽器書簽的誤使用有關本文將集中解決一些容易引起表單問題的典型情況用戶意外地重復發送數據在多步驟表單中直接使用中間表單

數據復制

  通過表單重復發送數據是一個常見的情況但是它會帶來問題在理想的情況下用戶在一個 Web 站點遇到一個表單用正確的數據類型填充它將它提交給處理數據的服務器然後作為回應發送給用戶一個確認頁這時用戶就可以再去做別的如果用戶重新訪問前面那一頁使用back 按鈕然後無意中再將數據發送一次那將會出現什麼情形呢?如果你沒有預料到這一場景並且有所准備數據就將被重新傳送給服務器並且再處理一次試想這些數據是一份訂單或旅館預約那將會帶來很不愉快的結果

終止重復數據傳輸

  為了避免那些錯誤地重復發送給服務器的數據可以在服務器側進行一些校驗來確定用戶能 意識到他們正在發送數據這裡使用的例子包含一個有單一文本框的簡單表單表單接收一些文本然後將其發送到一個顯示它們的ASP頁 為確保用戶不將同樣的信息發送兩次需要指示數據已經被服務器接收到存儲這些信息的最好的地方是一個session變量定義一個session變量Session(submitted) 當用戶第一次到達這個表單時將它初始化為False在用戶進行最初的數據傳輸時將它設置為true 如果用戶在當前的session期間重新訪問這個表單將出現相關重復提交信息
所以用戶只能是在有意的情況下向服務器重復發送數據現在來看看執行這一校驗的代碼建立表單並且校驗已發送數據的ASP頁(在下載處為formasp)有以下結構
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
〈 % If Session(submitted) Then % 〉
〈 ! Code showing the warning message
〈 % Else % 〉
〈 ! Code showing the form
〈 % End If % 〉
〈 /BODY 〉
〈 /HTML 〉

  表單和警告信息都是從同一個ASP頁創建的表單包括標准的HTML代碼引用ManageFormasp頁作為它的ACTION 屬性

〈 FORM METHOD=post ACTION=ManageFormasp
Send me some data:
〈 INPUT TYPE=text NAME=data
〈 P 〉
〈 INPUT TYPE=submit VALUE=Submit
〈 INPUT TYPE=reset VALUE=Cancel
〈 /FORM 〉

ManageFormasp 頁接收用戶發送的文本顯示它並將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) { documentAnswerFormanswervalue = answer documentAnswerFormsubmit() }
〈 /SCRIPT 〉
You have already submitted some information to this Web site
〈 BR 〉 Do you want submit again?
〈 P 〉
〈 FORM NAME=AnswerForm METHOD=post ACTION=CheckAnswerasp
〈 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() 設置這個函數還將它發送給CheckAnswerasp 頁以執行正確的重定向如果用戶選擇了No按鈕CheckAnswerasp 檢驗隱含控制的值並將其重定向到一個普通 welcome 頁反之就將session 變量submitted設置為False 並再次將其重定向到表單頁
〈 % If Request(answer) = Y Then Session(submitted) = False ResponseRedirect formasp Else ResponseRedirect End If % 〉

控制浏覽器緩沖器

  如果你已經實施了以上方法你會發現只有當你在浏覽器的地址文本框內鍵入URL來回到這個 表單時此方法才奏效它依靠的是浏覽器的緩沖器機制如果你使用back按鈕來返回頁浏覽器就檢測它的緩沖器來找到該頁的副本它將使用緩存的頁而不是向服務器發出請求所以服務器就 不能在session 變量submitted上進行校驗為了避免這種情況就要抑制浏覽器的頁緩沖器這通過在表單頁中處理Response對象來實現取消頁緩沖器有多種方法所有這些方法都要依靠HTTP頭文件中到浏覽器的地址指示但是所有浏覽器對服務器發送的指示反應不同所以說最好能多發送一些指示來為更多的浏覽器抑制緩沖器按以下代碼所示

〈 % ResponseAddHeader cachecontrol private ResponseAddHeader pragma nocache ResponseExpiresAbsolute = #January ::# ResponseExpires= % 〉

  以上代碼的頭兩行使用Response 對象的AddHeader 方法來將頭信息附加到HTTP頭文件中 Expires 和 ExpiresAbsolute 屬性用浏覽器緩沖器中頁的持續時間信息來標記當前頁在表單頁中這些行必須要插入在所有代碼之前因為她們所引用的信息放置在HTTP頭文件中在所有輸出之前發送給浏覽器

多步驟表單

  如果一個表單需要許多數據那麼最好將你要求的數據劃分成多個小表單這樣使用戶可以一步一步地填充表單而不用等待表單加載許多HTML控制另外還有一些情況表單中的某些控制不完全必要並且可以用已經提交的數據逐行填充使用多步驟表單允許顯示倚賴於用戶以前答案的定制表單如果用戶在浏覽器中將一個中間表單設置為書簽的話就會產生問題在隨後的一個session中用戶就試圖直接到達這個表單並提交數據這些數據已經在上下文范圍之外因為本來應該在前面 表單收集的session 數據丟失了

避免使用中間步驟表單

  為了避免這些問題可以存儲當前數據收集的狀態這個狀態可以用一個session 變量來代表 來記錄是否執行了一個特定的步驟用戶是否填充了給出的表單在一個多步驟表單中每個表單都可以通過一個Boolean型的session變量來實現如果有關表單沒有被處理變量就為False 反之就是True下載部分的第二個例子顯示一個兩步驟表單第一個表單要求用戶名第二個表單顯示一個組合框它的列表項要依賴第一個表單所提供的用戶名第一個表單與一個session變量requested相關聯你可以想象出來第二個表單與變量requested相關聯當用戶要求第一個表單(formasp) 時session變量 requested 被設置為 True :

〈 FORM METHOD=post ACTION=formasp
Your name: 〈 INPUT TYPE=text NAME=name
〈 P 〉
〈 INPUT TYPE=submit VALUE=Submit
〈 INPUT TYPE=reset VALUE=Cancel
〈 /FORM 〉
〈 % Session(requested) = True % 〉

  這個值將由下一個表單( formasp ) 來校驗以確定是否滿足了要求事實上當用戶要求第二個表單時校驗requested 變量如果為True就向浏覽器發送第二個表單並將requested變量設置為True如果為False 就意味著用戶想要直接使用第二個表單於是浏覽器就重定向到第一個表單以下代碼是第二個表單的ASP頁

〈 % If Session(requested) Then % 〉
〈 HTML 〉
〈 HEAD 〉
〈 /HEAD 〉
〈 BODY 〉
〈 ! Code for the second form
〈 % Session(requested) = True Else ResponseRedirect formasp End If % 〉
〈 /BODY 〉
〈 /HTML 〉

  要注意對requested 的校驗必須要在〈 HTML 〉記錄之前進行這樣就允許可能的重定向實際上重定向是對浏覽器的指示它出現在HTTP頭文件中在所有的HTML代碼之前

結論

  本文所示范的兩種技巧允許ASP開發人員對某些奇怪的情況有所控制這些奇怪情況會造成用戶 通過一個Web 表單向服務器重復發送數據每個技巧解決一個特定問題所以最好將兩者混合使用在ASP應用程序每個表單中管理兩個session 變量
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19718.html
  • 上一篇文章:

  • 下一篇文章:
  • Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.