验证
检验输入数据是否符合规定的格式、范围和约束条件的处理过程。包括字符数限制、字符类型检查、格式验证等。
验证 (validation) 是确认用户输入的数据、或系统之间传递的数据是否满足预期条件的处理过程。表单中填写的邮箱地址是否符合正确的格式、密码是否达到了最低字符数要求、手机号是否全部由数字构成。这些都是验证的具体实例。验证不只是为了挑出错误,更是为了在数据进入数据库和后续处理之前,把不符合前提的输入拦在门外。
验证按执行的位置分为两类。客户端验证在浏览器端即时返回反馈,用户不必等到提交之后才知道哪里填错了,因此能明显提升使用体验。HTML5 的 required、maxlength、pattern 属性以及 JavaScript 的动态检查都属于这一类。服务端验证则在服务器上做最终校验,负责保障安全性。由于客户端的检查可以通过开发者工具或直接构造请求轻松绕过,服务端验证在任何情况下都不可省略。两者不是二选一的关系,而是分工。
与字符数相关的验证是最基本也最常见的模式。X (原 Twitter) 的加权 280 单位限制 (中文字符每个算作 2 个单位,因此纯中文帖子实质约 140 字)、短信的 70 字 (中文) 限制、数据库 VARCHAR 列的上限等,几乎所有系统都存在字符数约束。这里真正棘手的问题是"什么算一个字符"。emoji 👨👩👧👦 看起来是 1 个字符,但在 Unicode 中由 7 个码点 (4 个人物 emoji + 3 个 ZWJ) 组成。不同平台对它计为 1 个字符还是 7 个字符各不相同,因此实现验证时必须先把字符数的定义讲清楚。数据库一侧还要区分上限是按字符算还是按字节算:在 UTF-8 中一个汉字要占 3 个字节,按字节设限时能存进去的汉字数会远少于预期。
字符类型的验证同样重要。中文表单中常见"仅限中文字符"、"仅限半角英文数字"这类约束,通常用正则表达式 /^[\u4e00-\u9fff]+$/ (基本区汉字) 或 /^[a-zA-Z0-9]+$/ (半角英文数字) 来检查。但需要注意边界情况:上面的范围只覆盖基本区,扩展区的汉字会被判为非法,姓名中含有生僻字的用户会因此无法完成注册;全角与半角的数字、字母外观相近而码位不同;带声调符号的拼音是否允许,也要事先约定。
格式验证用于校验邮箱地址、URL、日期、邮政编码等的格式。邮箱地址的正则表达式如果要完全符合 RFC 5322,会变得极其复杂而难以维护,因此实务中通常采用简化的模式做初步筛查,最终通过发送确认邮件来验证地址是否真的可达。格式看起来合法并不等于地址真实存在,这一点需要在设计时就分清。
验证错误消息的设计直接影响产品质量。与其只显示"输入错误",不如明确告知"密码需要 8 个字符以上,且包含字母和数字",让用户一眼看出问题出在哪里、怎么做才能通过。错误消息本身也受字符数的限制 (移动端屏幕的显示宽度、工具提示的最大长度等),因此需要在有限的字数里做到既简洁又明确。