四種表單驗證方法的分析和比較

前言

任何能夠交互的站點都有輸入表單,只要有可能,就應該對用戶輸入的數據進行驗證。不管服務器後端是什麼樣的系統,都不肯意把時間浪費在一些無效的信息上,必須對錶單數據進行校驗,如有不符合規定的表單輸入,應及時返回並給出相應的提示信息。本文將列舉四種不一樣原理的表單驗證方法,並給出各方法在 PHP 服務器上的實現。後端

瀏覽器端驗證

傳統上,表單數據通常都經過瀏覽器端的 Javascript 驗證。瀏覽器端的驗證速度快,如有不符合要求的輸入,響應信息快速的返回給用戶。因爲驗證數據不須要提交給服務器,不會加劇服務器的負載。一個瀏覽器端驗證的過程如圖 1 所示,表單提交,若經過驗證則提交服務器處理,不成功則回饋給用戶。瀏覽器

圖 1. 瀏覽器端驗證原理圖服務器

clipboard.png

本文給出的各類表單驗證方法 源代碼 均以一個簡單的表單爲例,該表單包含「UserName」和「Password」兩個文本輸入框,及一個「Submit」按鈕。代碼清單 1 給出了瀏覽器端 Javascript 驗證的例子。若「UserName」或「Password」輸入不符合要求,經過彈出框的形式提示用戶,並返回 false, 中止表單提交。網絡

清單 1. 瀏覽器端 Javascript 驗證代碼app

function validform(thisForm) 
  { 
     error_string = ""; 
     if((message=checkusername(thisForm.username))!="") 
       { 
         error_string="UserName:"
         error_string += message; 
         alert(error_string); 
         return false; 
        } 
     if((message = checkpassword(thisForm.pass))!="") 
       { 
         error_string="Password:"
         error_string += message; 
         alert(error_string); 
         return false; 
        }   
      return true;
   }

從圖 1 能夠看出這種表單驗證方法有一個致命的缺點,不少工具能夠在表單檢驗事後、瀏覽器發送請求前截取表單數據,攻擊者能夠修改請求中的數據,從而繞過 JavaScript,將惡意數據注入服務器,這樣會增長 XSS(全稱 Cross Site Scripting)攻擊的機率。對於通常的網站,都不同意採用瀏覽器端的表單驗證方法。函數

瀏覽器端和服務器端雙重驗證

瀏覽器端和服務器端雙重驗證方法在瀏覽器端驗證方法基礎上增長服務器端的驗證,其原理如圖 2 所示,該方法增長服務器端的驗證,彌補了傳統瀏覽器端驗證的缺點。若表單輸入不符合要求,瀏覽器端的 Javascript 驗證能很快地給出響應,而服務器端的驗證則能夠防止惡意用戶繞過 Javascript 驗證,保證最終數據的準確性。工具

圖 2. 瀏覽器端和服務器端雙重驗證原理圖post

clipboard.png

除了客戶端 Javascript 驗證,該方法增長了服務器端的 PHP 驗證,示例代碼如清單 2 所示,checkusername() 和 checkpassword() 是 PHP 語言 編寫的兩個驗證接口函數,根據 $error 結果,肯定表單的有效性。網站

清單 2. 服務器端表單的 PHP 驗證this

if(isset($_POST['username'])) 
{ 
 $usermsg  = checkusername($_POST['username']); 
 if($usermsg != '') 
   $error = true; 
 if(isset($_POST['pass'])) 
 { 
   $passmsg = checkpassword($_POST['pass']); 
   if($passmsg != '') 
   $error = true; 
 } 
}

此方法的缺點一目瞭然,必須維護兩份代碼實現相同的功能,增長開發人員的工做量,不利於後續開發。瀏覽器端和服務器端雙重驗證方法也存在一個風險,對有些表單驗證的規則服務器也許不想公開給用戶,而瀏覽器拷貝了服務器端驗證的功能,向用戶公佈驗證規則。

服務器端驗證

綜合上述兩種驗證方法,如今考慮使用服務器端的驗證方法,該方法結構很是簡單,其原理如圖 3 所示。客戶端負責表單提交,服務器端驗證表單,若發現錯誤數據,則回傳表單頁面,錯誤信息被加到同一頁面中。若驗證經過,則處理表單。

圖 3. 服務器端驗證原理圖

clipboard.png

此方法在遇到非法輸入須要回傳表單時,除了加載錯誤提示信息在此頁面上,還必須注意,此時表單內容必須維持表單提交時的用戶輸入,這樣用戶才能將錯誤的表單輸入與錯誤提示信息聯繫起來,有助於用戶填入正確的輸入。能夠藉助 DOM 技術 中的 appendChild 功能追加顯示相關的錯誤的提示信息,其實現如代碼清單 3 所示,其效果能夠參考圖 4。

清單 3. 利用 DOM 技術實現提示信息代碼

find_obj = document.getElementsByName("username"); 
 var sp1 = document.createElement('span'); 
 sp1.className= 'formerror'; 
 sp1.appendChild(document.createTextNode(usermsg)); 
 find_obj[0].parentNode.appendChild(sp1); 
 
 find_obj = document.getElementsByName("pass"); 
 var sp2 = document.createElement('span'); 
 sp2.className= 'formerror'; 
 sp2.appendChild(document.createTextNode(passmsg)); 
 find_obj[0].parentNode.appendChild(sp2);

圖 4. 加載錯誤信息效果圖

clipboard.png

因爲驗證交由服務器端處理,該方法的輸入響應速度不如瀏覽器端驗證,主要受網絡繁忙及服務器荷載的影響。同時,若同一頁面的其餘表單耗時較大,此回傳頁面方法的響應時間會進一步加大。

基於 Ajax 技術的驗證

基於 Ajax 技術的表單驗證技術綜合了服務器端驗證,瀏覽器端及服務器端雙重驗證方法的優勢,摒棄了二者的缺點。服務器端驗證方法結構清晰,能夠防止惡意攻擊,其主要問題在於若輸入錯誤表單信息,需重傳整個頁面,同時若同一頁面有多個表單,回傳整個頁面可能會增長用戶等待的時間。瀏覽器端及服務器端的雙重驗證響應速度快,其問題在於代碼冗餘。

基於 Ajax 技術的驗證方法也須要作兩次驗證:首先是回饋驗證,不管表單數據準確與否,服務器均給出反饋信息,其做用等同於雙重驗證中的瀏覽器端的驗證;表單處理前的驗證防止惡意修改,其做用等同於雙重驗證中的服務器端的驗證。其原理如圖 5 所示,一旦有表單提交,首先構建表單信息字段,交由 Ajax engine 發送給服務器端驗證,服務器將驗證結果發送給用戶,客戶端根據回饋信息,判斷表單輸入是否正常,在 Ajax 技術下,對用戶而言,以上操做均在後臺運行,不會影響當前頁面各表單的狀態。如果非法輸入,則回饋提示信息給用戶;如果正常輸入,客戶端將按照正常方法提交表單。爲了防止惡意修改,表單處理以前還需驗證,此步驗證與以前驗證共用代碼。

圖 5. 基於 Ajax 技術驗證原理圖

clipboard.png

有關 Ajax 技術的知識,能夠參考 developerWorks 上的 系列文章。Ajax 核心概念之一是 XMLHttpRequest 對象,這是一個 JavaScript 對象,建立該對象時,各類瀏覽器方法有所不一樣,具體實現能夠參考 源代碼。

回饋驗證主要涉及兩個問題:首先是構建驗證字段,其次是回饋信息的格式。

因爲驗證字段和正常表單字段共用驗證代碼,驗證字段格式徹底遵循表單提交時的格式。爲某表單構建驗證字段代碼如清單 4 所示。其中 checkflag 字段的做用是區分兩種驗證。

清單 4. 構建驗證字段代碼

var postData = ""; 
var fields = form.elements; 
for (var i=0; i < fields.length; i++) { 
if (fields[i].name != "") { 
     type = fields[i].type; 
      if ((type == 'radio') || (type == 'checkbox')) { 
        if (!fields[i].checked) { continue; } 
   } 
if ((type == 'submit')&&(!(fields[i].name == submitName))) { 
      continue; 
} 
if (postData) { postData += "&"; } 
postData += fields[i].name + "=" + encodeURIComponent(fields[i].value); 
         } 
} 
    postData += "&checkflag=1";

回饋信息主要在瀏覽端的 Javascript 中處理,不一樣的格式須要不一樣的處理方法。在傳統 Ajax 動態頁面處理中,回饋信息包含大量信息,採用 xml 格式,能夠藉助 DOM 技術處理,簡化程序。在本例中,回饋信息只包含驗證結果信息,簡單數據格式就能知足要求,客戶端的 Javascript 分析回饋信息,根據結果肯定是否提交完整的表單,具體實現請參考源代碼。

基於 Ajax 技術的驗證方法代碼相對比較複雜,錯誤的表單須要來回兩次網絡交互,而正確的提交則須要三次網絡交互。該驗證方法的響應時間與網絡繁忙程度有很大的關係。相對於純服務器端驗證,該方法在驗證階段不須要從新下載整個頁面,在多個表單共存在同一頁面的場合,基於 Ajax 技術的驗證方法不會影響同一頁面的其它表單。

小結

上述四種驗證方法各有優缺點,用戶應該根據需求選擇不一樣的方法。瀏覽器端驗證方法適用於對錶單輸入要求並非特別嚴格的場所;瀏覽器端和服務器端雙重驗證應用比較普遍,可是該方法不利於後續開發;服務器端驗證方法結構簡單,可是開發代碼相對複雜;基於 Ajax 技術的驗證方法,對網絡的要求高,可是該方法結構清晰,表單驗證與表單處理過程分離但共用驗證代碼,簡化開發人員的工做。

相關文章
相關標籤/搜索