`
yingyingol
  • 浏览: 739332 次
文章分类
社区版块
存档分类
最新评论

四种表单验证方法的分析和比较

 
阅读更多
对交互站点而言,快速、高效、友好的表单验证有利于用户体验及站点维护。本文主要通过分析比较表单验证方法的优缺点,得出各方法相应的适用场合。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

前言

任何可以交互的站点都有输入表单,只要有可能,就应该对用户输入的数据进行验证。无论服务器后端是什么样的系统,都不愿意把时间浪费在一些无效的信息上,必须对表单数据进行校验,若有不符合规定的表单输入,应及时返回并给出相应的提示信息。本文将列举四种不同原理的表单验证方法,并给出各方法在 PHP 服务器上的实现。




回页首


浏览器端验证

传统上,表单数据一般都通过浏览器端的 Javascript 验证。浏览器端的验证速度快,若有不符合要求的输入,响应信息快速的返回给用户。由于验证数据不需要提交给服务器,不会加重服务器的负载。一个浏览器端验证的过程如图 1 所示,表单提交,若通过验证则提交服务器处理,不成功则回馈给用户。


图 1. 浏览器端验证原理图
图 1. 浏览器端验证原理图

本文给出的各种表单验证方法 源代码 均以一个简单的表单为例,该表单包含“UserName”和“Password”两个文本输入框,及一个“Submit”按钮。代码清单 1 给出了浏览器端 Javascript 验证的例子。若“UserName”或“Password”输入不符合要求,通过弹出框的形式提示用户,并返回 false, 停止表单提交。


清单 1. 浏览器端 Javascript 验证代码

				  
 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. 浏览器端和服务器端双重验证原理图
图 2. 浏览器端和服务器端双重验证原理图

除了客户端 Javascript 验证,该方法增加了服务器端的 PHP 验证,示例代码如清单 2 所示,checkusername() 和 checkpassword() 是 PHP 语言 编写的两个验证接口函数,根据 $error 结果,确定表单的有效性。


清单 2. 服务器端表单的 PHP 验证

				  
 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. 服务器端验证原理图
图 3. 服务器端验证原理图

此方法在遇到非法输入需要回传表单时,除了加载错误提示信息在此页面上,还必须注意,此时表单内容必须维持表单提交时的用户输入,这样用户才能将错误的表单输入与错误提示信息联系起来,有助于用户填入正确的输入。可以借助 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. 加载错误信息效果图
图 4. 加载错误信息效果图

由于验证交由服务器端处理,该方法的输入响应速度不如浏览器端验证,主要受网络繁忙及服务器荷载的影响。同时,若同一页面的其他表单耗时较大,此回传页面方法的响应时间会进一步加大。




回页首


基于 Ajax 技术的验证

基于 Ajax 技术的表单验证技术综合了服务器端验证,浏览器端及服务器端双重验证方法的优点,摒弃了两者的缺点。服务器端验证方法结构清晰,可以防止恶意攻击,其主要问题在于若输入错误表单信息,需重传整个页面,同时若同一页面有多个表单,回传整个页面可能会增加用户等待的时间。浏览器端及服务器端的双重验证响应速度快,其问题在于代码冗余。

基于 Ajax 技术的验证方法也需要做两次验证:首先是回馈验证,无论表单数据准确与否,服务器均给出反馈信息,其作用等同于双重验证中的浏览器端的验证;表单处理前的验证防止恶意修改,其作用等同于双重验证中的服务器端的验证。其原理如图 5 所示,一旦有表单提交,首先构建表单信息字段,交由 Ajax engine 发送给服务器端验证,服务器将验证结果发送给用户,客户端根据回馈信息,判断表单输入是否正常,在 Ajax 技术下,对用户而言,以上操作均在后台运行,不会影响当前页面各表单的状态。若是非法输入,则回馈提示信息给用户;若是正常输入,客户端将按照正常方法提交表单。为了防止恶意修改,表单处理之前还需验证,此步验证与之前验证共用代码。


图 5. 基于 Ajax 技术验证原理图
图 5. 基于 Ajax 技术验证原理图

有关 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 技术的验证方法,对网络的要求高,但是该方法结构清晰,表单验证与表单处理过程分离但共用验证代码,简化开发人员的工作。





回页首


下载

描述 名字 大小 下载方法 示例代码
code.zip 2.8KB HTTP
关于下载方法的信息


参考资料


关于作者

胡丽霞,IBM 中国开发中心软件工程师,主要从事 BladeCenter 相关的开发测试工作。

分享到:
评论

相关推荐

    在ASP网站设计中表单验证

    在ASP网站设计中表单验证上面提到了两个不同的环境,服务器端和客户端,客户端验证实际上就是包含在已下载的页面中,当用户提交表单时候,它直接在已下载到本地的页面中调用script来进行验证,这样可以减少服务器端...

    用户注册表单验证分析.pdf

    用户注册表单验证分析

    php常用表单验证类库

    php常用表单验证类用法,实例分析了php针对表单元素常用验证技巧。数据出库 还原 特殊字符 传入值可为字符串 或 一/二维数组,数据显示 还原 数据格式 主要用于内容输出 传入值可为字符串 或 一/二维数组。

    JQUERY简单表单验证,不错的。个人在用。

    JQUERY简单表单验证,不错的。个人在用。

    CodeIgniter表单验证方法实例详解

    主要介绍了CodeIgniter表单验证方法,结合实例形式详细分析了CodeIgniter进行表单验证的具体步骤与相关实现技巧,需要的朋友可以参考下

    Laravel中使用FormRequest进行表单验证方法及问题汇总

    今天天气不错,我们来说说表单验证。 Controller中做表单验证 有的同学把表单验证逻辑写在Controller中,例如这个对用户提交评论内容的验证: &lt;?php // ... use Validator; class CommentControlle

    在Vant的基础上实现添加表单验证框架的方法示例

    例如它不内置表单验证,接下来,我把自己实现验证框架的思路分享出来。 分析需求 我们找的插件主要能解决以下问题 支持中文 适应UI框架 分组验证 动态验证(数据动态,规则动态) 去网络上搜索了一些框架,...

    Laravel框架表单验证操作实例分析

    主要介绍了Laravel框架表单验证操作,结合实例形式分析了Laravel框架表单验证相关的表单数据提交、验证、错误信息提示等相关操作技巧,需要的朋友可以参考下

    AngularJS表单验证功能分析

    本文实例讲述了AngularJS表单验证功能。分享给大家供大家参考,具体如下: 在AngularJS的管辖下,每个表单form都会创建一个ngFormController的一个实例。在表单里面的每个input都会创建一个在这个实例下的...

    JS使用正则表达式实现常用的表单验证功能分析

    主要介绍了JS使用正则表达式实现常用的表单验证功能,结合实例形式分析了JS基于正则表达式的表单验证功能原理、实现技巧与操作注意事项,需要的朋友可以参考下

    JS表单验证方法实例小结【电话、身份证号、Email、中文、特殊字符、身份证号等】

    主要介绍了JS表单验证方法,结合实例形式总结分析了常用的表单验证技巧,包括电话、身份证号、Email、中文、特殊字符、身份证号等验证方法,需要的朋友可以参考下

    js进行表单验证实例分析

    主要介绍了js进行表单验证的方法,实例分析了各种常见的js表单验证技巧,需要的朋友可以参考下

    php常用表单验证类.zip

    主要介绍了php常用表单验证类用法,实例分析了php针对表单元素常用验证技巧。数据出库 还原 特殊字符 传入值可为字符串 或 一/二维数组,数据显示 还原 数据格式 主要用于内容输出 传入值可为字符串 或 一/二维数组。

    vue+elementUI实现表单和图片上传及验证功能示例

    本文实例讲述了vue+elementUI实现表单和图片上传及验证功能。...1、el-form的表单验证需要注意几个地方: a:el-form-item的prop值需要和表单标签的v-model值保持一致 例如: 姓名: prop=name&gt; &lt;e

    yii用户注册表单验证实例

    主要介绍了yii用户注册表单验证,以实例形式详细分析了基于yii框架的用户注册表单验证功能模型,视图及控制器层具体实现技巧,需要的朋友可以参考下

    Yii框架表单提交验证功能分析

    本文实例讲述了Yii框架表单提交验证功能。分享给大家供大家参考,具体如下: 一、前端提交的三种方式 前面已经提出,表单提交一共只有三种方式。 1. 前端原生html (1)原生html标签 首先,直接使用html标签的input,...

    详解正则表达式表单验证实例

    下面通过一段代码给大家分析表单验证正则表达式,具体代码如下: &lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-"&gt; &lt;title&gt;正则验证常用表单方法&lt;/title&gt; &...

Global site tag (gtag.js) - Google Analytics