HTML的pattern属性无法真正校验身份证号码,因其不支持负向断言且无法计算第18位校验码;必须结合JS格式正则粗筛与国标加权算法精验,并在后端完整复现同一逻辑。

HTML 的 pattern 属性不能真正校验身份证号码
直接在 里用 pattern 做身份证校验,大概率会漏判或误判。HTML5 的 pattern 只支持 ECMAScript 旧版正则(不支持 (? 这类负向断言),也没法做最后一位校验码的逻辑计算——而18位身份证的第18位是根据前17位加权模11算出来的,纯正则根本没法覆盖。
常见错误现象:
– 输入 11010119900307299X(合法)却提示不匹配
– 输入 110101199003072999(校验码错)却被通过
– 输入带空格或短横线的 110101 1990-03-07 299X,pattern 拦不住,后端又没二次校验
用 JavaScript 手动校验更可靠,关键在第18位计算
必须拆成两步:先用正则粗筛格式,再用算法验证校验码。浏览器端校验只是体验优化,后端仍需完整复现同一套逻辑。
实操建议:
- 格式正则用
/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/—— 覆盖年份范围、月份日范围、末位允许X/x - 校验码计算必须按国标 GB11643-1999:对前17位分别乘以权重
[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2],求和后对11取模,再对照余数映射表['1','0','X','9','8','7','6','5','4','3','2'] - 注意大小写:末位
X必须大写参与计算,但用户输入x应自动转为大写再校验 - 别忽略全角字符问题:用户可能粘贴进全角数字或空格,建议先
.replace(/[\u3000-\u303f\uFF00-\uFFEF]/g, '')清洗
input 的 pattern 可以保留,但仅作辅助提示
虽然它不能替代真实校验,但配合 title 属性能减少低级误输。比如用户随手输个 123,浏览器会直接标红并显示提示文字。
示例写法:
<input type="text" pattern="[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]" title="请输入正确的18位身份证号码,末位可为X" maxlength="18">
注意点:
-
maxlength="18"必须加上,否则用户可能输超长字符串绕过pattern -
title提示要具体,避免只写“格式错误”这种无意义信息 - 这个正则不检查年月日有效性(比如 2025-02-30),所以仍需 JS 补充日期合法性判断
后端必须独立实现同一套校验逻辑
前端任何校验都可被绕过。如果后端只简单用正则匹配 /^\d{17}[\dXx]$/,就等于没校验。
容易被忽略的地方:
- 15位身份证已基本弃用,但仍有老旧系统残留,若业务明确不接受,后端要拒绝而非自动补零升位
- 地区码(前6位)应查表校验是否为有效行政区划,而非只看数字范围;例如
999999是无效开头 - 加权计算时,字符串每一位要转成数字再乘权重,别忘了
parseInt(char, 10),否则"0"开头可能被当八进制 - Node.js 等环境要注意
X的 Unicode 编码,建议统一用.toUpperCase()再取.charCodeAt(0)
真正可靠的身份证校验,从来不是一串正则能搞定的事。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











