JavaScript实现身份证号校验与前端验证提示

认真发呆
认真发呆
发布时间:2026-10-13 | 2人浏览过
原创

利用JavaScript在客户端对输入的中国身份证号码进行格式、省份、生日逻辑及校验位的全面验证,并展示具体的错误提示信息。

实现目标与核心逻辑

在进行身份信息录入时,实时的前端校验能有效提升用户体验并减少服务器压力。完整的身份证校验主要包含以下四个维度:

  1. 格式规范:确认号码长度为15位或18位,且字符符合数字与X的规范。
  2. 省份归属:根据前两位数字匹配合法的省级行政区代码。
  3. 时间逻辑:解析出生年月日,判断其是否为一个合法的真实日期(如非闰年的2月29日)。
  4. 校验位算法:依据国家标准GB 11643-1999,利用加权因子计算最后一位校验码,确保数据未被随意篡改。

准备工作与环境要求

本方案基于原生JavaScript编写,无需额外依赖库即可在现代浏览器中运行。使用前需确保页面上存在用于显示验证结果的DOM元素(如 <span>),以便动态展示错误信息。

代码实现步骤

第1步:构建主校验入口函数

该函数作为统一调用接口,按顺序触发各项子检查,并根据结果返回布尔值。

function checkIdCard(idValue) {
    // 1. 基础非空与默认值检查
    if (idValue === '身份证号') { 
        showMsg('span_username', true, '身份证号不能为空'); 
        return false; 
    }
    
    // 2. 基础格式校验
    if (isCardNo(idValue) === false) {
        showMsg('span_username', true, '您输入的身份证号码格式不正确');
        return false;
    }
    
    // 3. 省份合法性校验
    if (checkProvince(idValue) === false) {
        showMsg('span_username', true, '您输入的身份证地区代码无效');
        return false;
    }
    
    // 4. 生日逻辑校验
    if (checkBirthday(idValue) === false) {
        showMsg('span_username', true, '出生日期不存在或年份范围异常');
        return false;
    }
    
    // 5. 尾缀校验位校验
    if (checkParity(idValue) === false) {
        showMsg('span_username', true, '身份证校验位不正确');
        return false;
    }
    
    // 全部通过
    showMsg('span_username', false);
    return true;
}

// 辅助函数:控制错误提示框的显隐与内容
function showMsg(spanId, show, msg) {
    var el = document.getElementById(spanId);
    if (!el) return;
    if (show) {
        el.style.display = 'block';
        el.innerHTML = msg;
        el.className = 'error-msg'; // 假设添加了红色样式类
    } else {
        el.style.display = 'none';
        el.innerHTML = '';
    }
}

第2步:定义省份代码字典与格式正则

建立省、自治区、直辖市代码表,并使用正则表达式锁定号码的长度与类型特征。

// 身份证省的编码映射
var vcity = {
    11:"北京", 12:"天津", 13:"河北", 14:"山西", 15:"内蒙古",
    21:"辽宁", 22:"吉林", 23:"黑龙江", 31:"上海", 32:"江苏",
    33:"浙江", 34:"安徽", 35:"福建", 36:"江西", 37:"山东",
    41:"河南", 42:"湖北", 43:"湖南", 44:"广东", 45:"广西",
    46:"海南", 50:"重庆", 51:"四川", 52:"贵州", 53:"云南",
    54:"西藏", 61:"陕西", 62:"甘肃", 63:"青海", 64:"宁夏",
    65:"新疆", 71:"台湾", 81:"香港", 82:"澳门", 91:"国外"
};

// 校验长度和类型
// 15位全数字;18位前17位数字,第18位为数字或X
var isCardNoRegex = /^(^\d{15}$)|(^\d{17}(\d|X|x)$)$/;

function isCardNo(card) {
    return isCardNoRegex.test(card);
}

function checkProvince(card) {
    var province = card.substr(0, 2);
    // 注意:某些旧系统可能使用字符串索引,需确保键类型为String
    return Object.prototype.hasOwnProperty.call(vcity, province);
}

第3步:实现生日逻辑与日期有效性验证

区分15位(年用2位表示)和18位身份证,提取出完整年份后,利用Date对象验证日期合法性,并限制合理的年龄范围(示例中设为3至100岁)。

function checkBirthday(card) {
    var len = card.length;
    var year, month, day;
    
    if (len == 15) {
        // 15位:YYYYMMDD -> 补全为 19YY-MM-DD
        var reFifteen = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/;
        var arrData = card.match(reFifteen);
        year = '19' + arrData[2];
        month = arrData[3];
        day = arrData[4];
    } else if (len == 18) {
        // 18位:YYYY-MM-DD
        var reEighteen = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})[0-9Xx]$/;
        var arrData = card.match(reEighteen);
        year = arrData[2];
        month = arrData[3];
        day = arrData[4];
    } else {
        return false;
    }
    
    return verifyBirthday(year, month, day);
}

function verifyBirthday(year, month, day) {
    var date = new Date(year, month - 1, day); // JS月份从0开始
    
    // 1. 检查日期是否被自动修正(例如输入2月30日会变成3月2日)
    if (date.getFullYear() != parseInt(year, 10) || 
        (date.getMonth() + 1) != parseInt(month, 10) || 
        date.getDate() != parseInt(day, 10)) {
        return false;
    }
    
    // 2. 检查年龄范围(可根据业务需求调整)
    var nowYear = new Date().getFullYear();
    var age = nowYear - parseInt(year, 10);
    if (age < 3 || age > 100) {
        return false;
    }
    
    return true;
}

第4步:执行15位转18位及校验位计算

这是最复杂的一步。所有15位身份证在计算校验位前需先扩充为18位。随后根据加权公式计算校验码。权重数组为 [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]。

function checkParity(card) {
    // 如果是15位,先转为18位再进行校验
    if (card.length == 15) {
        card = changeFivteenToEighteen(card);
    }
    
    if (card.length == 18) {
        var arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        var arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
        var sum = 0;
        
        // 计算加权和
        for(var i = 0; i < 17; i++) {
            sum += card.substr(i, 1) * arrInt[i];
        }
        
        // 取模并查表得到理论校验位
        var valnum = arrCh[sum % 11];
        
        // 比对原卡号最后一位(忽略大小写)
        return valnum.toLowerCase() == card.substr(17, 1).toLowerCase();
    }
    return false;
}

// 15位转18位专用函数
function changeFivteenToEighteen(card) {
    if (card.length != 15) return card;
    
    var arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    var arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
    var cardTemp = 0;
    
    // 插入年份 '19'
    card = card.substr(0, 6) + '19' + card.substr(6);
    
    // 计算校验位并追加
    for(var i = 0; i < 17; i++) {
        cardTemp += card.substr(i, 1) * arrInt[i];
    }
    
    return card + arrCh[cardTemp % 11];
}

HTML结构与应用方式

将上述JS函数引入页面后,可以在输入框的 onblur 事件中调用校验函数。下方展示了一个简单的输入框与错误提示区域的配合写法:

<input type="text" id="username" value="请输入身份证号" name="userid" onblur="if(this.value!=''){checkIdCard(this.value);} else {this.value='请输入身份证号';}">
<span id="span_username" style="color:red; display:none;"></span>

当用户输入完身份证号并离开焦点时,脚本会自动执行所有验证步骤。若验证通过,隐藏错误信息并返回true;若失败,则显示具体的错误原因,并将函数返回值标记为false,前端据此可阻止表单提交。

注意事项与局限性

此方法主要依靠本地正则和算法进行格式合法性检测。它无法验证该身份证号码是否在公安系统中真实存在(即无法识别假冒证件)。如果需要确保证件真实性,必须请求后端接口进行实名核验。

以上就是JavaScript实现验证身份证号的有效性并提示的详细内容,更多关于JavaScript前端校验的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表