表单校验

javascript/jquery

浏览数:225

2019-3-6

AD:资源代下载服务

洪荒时代:数据库校验

入库失败

话说在上古时期,人们通常不会在程序里做校验。由于关系型数据库几乎都是强类型的,如果输入的数据和数据库定义的类型不一致就会出错。

比如定义一个整型的「年龄」字段,但传入了一个神奇的非整型字符串,于是这个操作就入库失败了。

而且不仅是数据的类型,一些主外键关联、约束也成了业务的校验工具。

如果这种基于数据库字段的校验算是表单校验的话,那它应该就是最早的表单校验了。

入库检查

「人之初,性本善」,早期人们都认为这个世界上不会有坏人,没有人会去考虑安全性问题,人们都在愉快地写这种神奇的 SQL 语句。

sql = "SELECT 1 FROM `users` WHERE `username`='" & username & "' AND `passport`='" & passport & "'"

于是当 ‘or’=’or’ 这样的万能密码被造出来时,人们这才逐渐认识到这个问题的严重性,才开始过滤各种字符,于是有了程序层面的数据校验。

虽然上面的例子只是登录时的用户名密码校验,实际上这种校验在所有入库前都会做都必须做。

古代:提交校验

服务器端校验

随着 Web 的发展,业务也越来越复杂起来。这个年代的人们开始考虑如何做得更好,于是对业务数据做校验的情况就越来越普遍。比如在程序里检测输入的是否是一个电话号码、是否是电子邮箱地址等。

但是这一切依然是在服务器端做校验,这是因为这个阶段,浏览器端写代码这种事情并不是主流。甚至当时很多从平面设计转到网页设计的人都不知道网页上可以执行代码。

服务器端的校验毕竟是表单已经被提交之后才处理的。也许在祖国即将全面建成小康社会的现在,我们感受不到当年的痛。但是在 Ajax 的概念都没有流行以前,表单就是 HTML 的 FORM 元素,提交一个表单就是一个页面跳转的行为。即便是现在,也没人会希望产生多余的页面跳转,更何况是在 ADSL 拨号上网的年代了。

而且后端表单校验不通过时页面还要考虑如何恢复到提交之前的状态,否则就会造成表单校验失败后整个表单都要重新填写。于是就会出现大量这样的代码:

<form>
  <input name="xxx" value="<%=Request.Form("xxx")%>" />
  ...
</form>

上面这个例子还是比较简单的情况,因为只是文本框,要是 Checkbox、Radio、Select 之类的控件,还得写个循环去判断,开发起来那是相当恶心。

实际上当时很多开发人员根本就懒得做表单恢复这件事,于是不少页面确确实实存在提交失败后需要重新填写整个表单的情况,甚至如今去看一些比较古老的网站依然有这种现象。不过好在当时的用户对这种事情的容忍程度比较高,即便难用,用户也会觉得是自己傻逼。

客户端校验

由于做了大量不规范的表单恢复(比如上一段中的例子,我相信有很多人看到的瞬间就开始吐槽安全问题了),网页上可以注入的地方随处可见,于是 XSS 之风开始盛行。这时候人们才意识到居然还有这种操作,既然浏览器上可以执行这么强大的代码,为啥不把表单校验直接放在浏览器端做掉呢?

必须输入 123 才可以提交成功
<form onsubmit="if(xxx.value==123)alert('成功');else{alert('必须输入 123');return false;}">
  <input name="xxx" />
  <input type="submit" value="提交" />
</form>

这个阶段越来越多的表单校验被放到浏览器端来做,这样不仅可以省去表单恢复这样的恶心代码,还可以让用户体验起来更爽。这样的技术怎么可能不火?于是在浏览器端做表单校验变成了当年风靡一时的 Web 从业人员面试题,甚至各种培训机构也开始把它列入教材。

前端革命

Ajax 的流行是一个契机,加上 jQuery 的神助攻,无刷新提交开始席卷 Web 界。

这时候人们才意识到,原来在浏览器上还可以这么玩,于是后来各种前端框架层出不穷,同时也诞生了 Web 前端这个职业。

再后来,前后端分离以及前端的 MV* 开始流行,这才真正让 Web 前端这个职业真正掀起波浪。

近现代:快速校验

失焦校验

随着互联网的发展,人们开始越来越重视用户体验。在点击提交按钮之后对整个表单进行校验的做法已经无法满足了。

在这个阶段,失焦校验开始流行起来。之所以流行是因为直到 IE8,能够通过事件来检测控件输入变化的最快办法就是失焦了(文本框的 change 事件也是基于失焦)。

然而失焦校验并不是这个时期诞生的,很早以前人们刚学会通过 submit 事件做表单校验时就已经留意到了失焦校验,但当时只能够用来做一些浏览器端能够计算的校验而已,真正普及起来是在 Ajax 流行之后。一旦可以与服务器交互,失焦校验就几乎能够满足所有表单校验的业务场景。

直到现在,这种校验方式依然很流行。

输入校验

对于一些有追求的交互设计师,失校校验依然被认为是太慢了,他们希望更快地让用户知道自己的输入是错误的,于是前端又开始了基于 input 事件的校验。

初期为了兼容低版本浏览器还需要有很多黑科技,比如侦测键盘事件、使用计时器等方案,不仅开发成本高,而且还很容易出 Bug。后来随着 IE 的市场份额降低,这种做法才真正流行起来。

未来:无校验

超越光速

对于现代的表单校验,我们一直在追求的速度,希望将错误操作更快地通知给用户。那么如何才能更快呢?

速度的极致便是光速,爱因斯坦曾说过,突破光速甚至可以让时光倒流,此时因果律都不再适用。我们根本没必要因为用户的错误操作而去考虑如何纠正,只要用户不犯错,我们自然就不需要再去纠正。

颠覆因果

我认为,未来的表单可以变成无校验的形式。

事后去纠正用户的错误操作,无论多快,实际上错误都已经发生了。我们费力地思考如何纠正用户的错误,这已经是在结果上亡羊补牢了。不如考虑如何阻止用户犯错吧?只要做到让用户失去犯错的能力,表单校验就可以成为历史。

现实中,在控件设计上就可以规避掉错误输入。比如一些输入电子邮箱的控件设计,「@」符号自带其中,用户无法做到不输入「@」符号。这比起事后去做一次带「@」符号的检测要好得多。

再比如一个手机号输入控件,可以用一种 11 个格子的形式展示,首个数字 1 甚至都可以自动填入,并阻止修改。这比起我们现在用正则去匹配一个字符串是否是手机号要好得多。

当然,这只是最最最初级的水平,要真正做好这些还需要耗费不小的心力。

最后

我们能做到的只有揣着历史去预测有限的未来,真正的未来是什么样的没有人能够准确预言。或许十年后连「表单」这种东西都会不复存在,以后回过头来看现在的自己,可能只能一笑置之了。