HTML怎样做input身份证校验_HTML input身份证号校验方法【教程】

作者:袖梨 2026-06-05
HTML原生pattern仅支持正则匹配,无法校验身份证号等含算法逻辑的字段;必须用JavaScript在blur时执行加权求和+mod11校验,且后端须重复验证。

pattern 做前端简单校验,但别信它能防错

HTML 原生 pattern 只能做正则匹配,对身份证号这种有算法校验逻辑的字段,pattern 顶多拦住明显乱输的(比如纯字母、位数不对),但无法验证最后一位校验码是否正确。浏览器不会执行加权求和 + mod 11 这套逻辑。

常见错误是写成:<input pattern="^d{17}[dXx]$"> —— 这连 15 位旧号码都不支持,更别说校验码了。

  • 18 位身份证必须满足:前 17 位全数字,第 18 位是 0-9X(大小写都允许)
  • 必须校验第 18 位:用加权因子 [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2] 与前 17 位相乘求和,再对 11 取模,结果对应校验码表 ['1','0','X','9','8','7','6','5','4','3','2']
  • pattern 只建议作为辅助提示,比如:pattern="^d{17}[dXx]$" 配合 title="请输入18位身份证号",降低用户误输概率

onbluraddEventListener('blur') 触发 JS 校验

真实校验必须靠 JavaScript,在用户离开输入框时执行。不要用 oninput 实时校验——每打一个字都算一次校验码,体验卡顿且无必要。

示例关键逻辑:

立即学习“前端免费学习笔记(深入)”;

function validateIdCard(id) {  const reg = /^[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]$/;  if (!reg.test(id)) return false;  const factor = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];  const checkCode = ['1','0','X','9','8','7','6','5','4','3','2'];  const sum = id.slice(0, 17).split('').reduce((acc, cur, i) => acc + parseInt(cur) * factor[i], 0);  return checkCode[sum % 11].toUpperCase() === id[17].toUpperCase();}
  • 正则先筛格式(含出生日期合理性,如月份不超 12,日期不超当月天数),但注意:正则无法 100% 判定日期有效性(比如 20230230)
  • 加权计算必须用 parseInt() 转数字,否则字符串相乘会出错
  • 校验码比对要忽略大小写:id[17].toUpperCase()
  • 15 位老身份证已基本淘汰,若需兼容,得单独处理(补 '19' + 插入校验位),但当前绝大多数业务场景可直接拒绝

后端必须重校验,前端只是用户体验层

任何前端校验都能被绕过——禁用 JS、手动改 DOM、curl 直接 POST。所以 validateIdCard() 函数必须在服务端用相同逻辑再跑一遍。

  • Node.js 示例:用同一套逻辑写在 Express 中间件里;Python 后端用 re.match() + 手动加权计算
  • 不要依赖第三方库做校验(如某些 npm 包校验逻辑有 bug),自己实现 20 行以内的函数更可控
  • 如果接口返回 400 Bad Request,错误信息里不要暴露校验细节(比如“第18位应为X”),避免被用于枚举攻击

移动端 inputmode="numeric"inputmode="text" 的取舍

身份证号不能用 type="number",因为末尾 X 会导致输入被截断或报错。但用 type="text" 默认唤起全键盘,体验差。

  • 推荐:<input type="text" inputmode="numeric" pattern="[0-9Xx]*">
  • inputmode="numeric" 在 iOS/Android 大部分浏览器中会唤起数字键盘,用户输完再手动切字母键输 X
  • pattern="[0-9Xx]*" 是为了让 iOS 在数字键盘上显示 X 键(部分版本支持)
  • 别加 maxlength="18":15 位老证虽少,但加了会直接卡死输入,不如让 JS 校验后提示

前端校验只是减少无效提交,真正可靠的只有后端那一次计算。很多人写了正则就以为万事大吉,结果上线后发现“11010119900307299Q”这种明显错误的号也能过——因为没算校验码。

相关文章

精彩推荐