0

0

使用 Luhn 算法实现表单信用卡号验证

花韻仙語

花韻仙語

发布时间:2025-08-30 15:19:00

|

872人浏览过

|

来源于php中文网

原创

使用 luhn 算法实现表单信用卡号验证

本文详细介绍了如何在前端表单中集成自定义验证逻辑,特别是使用 Luhn 算法验证信用卡号。通过利用 HTML5 的原生表单验证 API 和 setCustomValidity 方法,您可以无缝地将复杂的验证规则(如 Luhn 算法)与浏览器内置的验证机制结合,为用户提供即时、友好的错误反馈,从而提升表单的健壮性和用户体验。

1. 前端表单验证的重要性与挑战

在现代 Web 应用中,表单验证是不可或缺的一环。良好的客户端验证不仅能提升用户体验,减少无效提交,还能减轻服务器端压力。HTML5 引入了原生的表单验证机制,如 required、type="email" 等属性,极大地简化了常见验证任务。然而,对于某些复杂的业务规则,例如信用卡号的 Luhn 算法验证,原生 HTML5 验证能力有限,需要结合 JavaScript 进行自定义扩展。

2. Luhn 算法原理与实现

Luhn 算法(也称为模 10 算法)是一种简单的校验和算法,常用于验证各种识别号码,包括信用卡号。其核心思想是通过对数字序列进行特定计算,判断其是否符合规则。

以下是 Luhn 算法的 JavaScript 实现:

/**
 * 校验给定的字符串是否符合 Luhn 算法规则
 * @param {string} value 待校验的数字字符串
 * @returns {boolean} 如果符合 Luhn 算法则返回 true,否则返回 false
 */
function checkLuhn(value) {
  // 接受只包含数字、破折号或空格的字符串
  if (/[^0-9-\s]+/.test(value)) return false;

  let nCheck = 0,
    nDigit = 0,
    bEven = false;
  // 移除所有非数字字符
  value = value.replace(/\D/g, "");

  // 从右向左遍历数字
  for (let n = value.length - 1; n >= 0; n--) {
    const cDigit = value.charAt(n);
    nDigit = parseInt(cDigit, 10);

    if (bEven) {
      // 偶数位(从右边开始数的第二位、第四位...)数字乘以2
      if ((nDigit *= 2) > 9) nDigit -= 9; // 如果结果大于9,则减去9
    }

    nCheck += nDigit; // 累加所有数字
    bEven = !bEven; // 切换奇偶标志
  }

  // 如果总和能被10整除,则校验通过
  return (nCheck % 10) === 0;
}

Luhn 算法步骤解析:

  1. 从右向左处理数字: 从信用卡号的最右边数字开始,向左依次处理。
  2. 隔位加倍: 从右边开始的第一个数字(校验位)不加倍,第二个数字加倍,第三个不加倍,第四个加倍,以此类推。
  3. 处理加倍结果: 如果加倍后的数字大于 9(例如 7 * 2 = 14),则将其各位数字相加(1 + 4 = 5),或者直接减去 9(14 - 9 = 5)。
  4. 求和: 将所有处理后的数字(未加倍的数字和加倍后处理的数字)相加。
  5. 模 10 校验: 如果最终的总和能被 10 整除,则该信用卡号是有效的。

3. 集成自定义验证与 setCustomValidity

HTML5 表单元素提供了一个 setCustomValidity() 方法,允许开发者设置自定义验证消息。当传入一个非空字符串时,该字段将被标记为无效,并显示该字符串作为验证消息;传入空字符串则表示字段有效。这是将自定义验证逻辑与浏览器原生验证机制无缝结合的关键。

以下是将 Luhn 算法集成到信用卡号输入字段的示例:

// 当信用卡号输入框内容变化时触发验证
$('#cc').on('input', function(){
  // 获取信用卡号输入框的 DOM 元素
  // 注意:这里需要确保 field 变量正确引用到输入框,
  // 否则 setCustomValidity 将无法调用
  const field = document.querySelector('#cardContainer input'); // 假设输入框在一个 id 为 'cardContainer' 的父元素内

  if (checkLuhn($('#cc').val())) {
    field.setCustomValidity(""); // 验证通过,清除自定义错误消息
  } else {
    field.setCustomValidity("Invalid field."); // 验证失败,设置自定义错误消息
  }
});

关键点说明:

  • 事件监听: 使用 input 事件监听器,可以在用户输入时实时进行验证,提供即时反馈。
  • 获取 DOM 元素: field 变量必须指向实际的 DOM 元素。在本例中,我们通过 document.querySelector('#cardContainer input') 获取,这要求 HTML 中信用卡输入框的父元素具有 id="cardContainer"。如果 id="cc" 在整个文档中是唯一的,也可以直接使用 document.getElementById('cc')。
  • setCustomValidity(""): 当 checkLuhn 返回 true 时,调用此方法清除任何自定义验证消息,使字段被浏览器视为有效。
  • setCustomValidity("Invalid field."): 当 checkLuhn 返回 false 时,调用此方法设置一个自定义错误消息,使字段被浏览器标记为无效,并在提交时阻止表单提交。

4. 整体表单验证流程

除了自定义 Luhn 算法验证,一个完整的表单通常还包含其他字段(如姓名、邮箱)的原生 HTML5 验证。以下是结合所有验证逻辑的表单提交处理流程:

动态WEB网站中的PHP和MySQL:直观的QuickPro指南第2版
动态WEB网站中的PHP和MySQL:直观的QuickPro指南第2版

动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包

下载
(function () {
  "use strict";

  const forms = document.querySelectorAll(".needs-validation");
  const result = document.getElementById("result");

  Array.prototype.slice.call(forms).forEach(function (form) {
    form.addEventListener(
      "submit",
      function (event) {
        // 在提交前,先执行所有验证(包括原生HTML5验证和通过setCustomValidity设置的自定义验证)
        if (!form.checkValidity()) {
          event.preventDefault(); // 阻止默认提交行为
          event.stopPropagation(); // 阻止事件冒泡

          // 聚焦到第一个无效字段
          form.querySelectorAll(":invalid")[0].focus();
        } else {
          // 如果所有字段都有效,则处理表单提交(例如通过 Fetch API 发送到后端)
          const formData = new FormData(form);
          event.preventDefault();
          event.stopPropagation();

          const object = {};
          formData.forEach((value, key) => {
            object[key] = value;
          });
          const json = JSON.stringify(object);
          result.innerHTML = "Please wait...";

          fetch("https://api.web3forms.com/submit", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Accept: "application/json"
            },
            body: json
          })
            .then(async (response) => {
              let json = await response.json();
              if (response.status === 200) {
                result.innerHTML = json.message;
                result.classList.remove("text-gray-500");
                result.classList.add("text-green-500");
              } else {
                console.log(response);
                result.innerHTML = json.message;
                result.classList.remove("text-gray-500");
                result.classList.add("text-red-500");
              }
            })
            .catch((error) => {
              console.log(error);
              result.innerHTML = "Something went wrong!";
            })
            .then(function () {
              form.reset(); // 重置表单
              form.classList.remove("was-validated"); // 移除验证样式
              setTimeout(() => {
                result.style.display = "none";
              }, 5000);
            });
        }
        form.classList.add("was-validated"); // 添加验证样式,触发CSS显示错误信息
      },
      false
    );
  });
})();

此流程的关键点:

  • form.checkValidity(): 这是 HTML5 表单验证 API 的核心。它会检查表单中所有带有验证规则(如 required、type="email"、pattern)的字段,以及通过 setCustomValidity() 设置了错误消息的字段。如果任何字段无效,它将返回 false。
  • 阻止默认行为: 当 form.checkValidity() 返回 false 时,调用 event.preventDefault() 和 event.stopPropagation() 来阻止表单的默认提交行为,并防止事件进一步传播。
  • was-validated 类: 在表单提交尝试后,通过添加 was-validated 类,可以触发 CSS 规则来显示验证反馈消息。

5. HTML 结构与样式

为了支持上述验证逻辑和错误消息显示,HTML 结构需要包含相应的输入字段、标签和反馈消息占位符。同时,CSS 样式用于控制错误消息的显示和输入框的视觉反馈。

HTML 结构示例(信用卡号部分):

Please provide your credit card number.
Please provide a valid credit card number.

CSS 样式示例:

.invalid-feedback,
.empty-feedback {
  display: none; /* 默认隐藏错误反馈 */
}

/* 当表单被标记为 'was-validated' 且输入框为空且无效时,显示 'empty-feedback' */
.was-validated :placeholder-shown:invalid ~ .empty-feedback {
  display: block;
}

/* 当表单被标记为 'was-validated' 且输入框非空但无效时,显示 'invalid-feedback' */
.was-validated :not(:placeholder-shown):invalid ~ .invalid-feedback {
  display: block;
}

/* 当输入框无效时,设置边框颜色 */
.is-invalid,
.was-validated :invalid {
  border-color: #dc3545; /* 红色边框 */
}

这些 CSS 规则利用了 :invalid、:placeholder-shown 等伪类和 ~ (兄弟选择器),配合 was-validated 类,实现了在不同验证状态下显示不同的错误消息和输入框样式。

6. 注意事项与最佳实践

  • 客户端与服务器端验证: 客户端验证是为了提供即时用户反馈和优化体验,但绝不能替代服务器端验证。所有提交到服务器的数据都必须在服务器端再次进行严格验证,以防止恶意攻击和数据损坏。
  • 用户体验: 确保错误消息清晰、具体且易于理解。实时验证(如 input 事件监听)可以显著提升用户体验,但对于复杂的验证逻辑,可以考虑使用防抖(debounce)或节流(throttle)技术,避免在用户快速输入时频繁触发计算。
  • 可访问性: 确保验证错误对屏幕阅读器等辅助技术是可访问的。使用 ARIA 属性(如 aria-invalid、aria-describedby)可以增强表单的可访问性。
  • 代码组织: 将验证逻辑模块化,例如将 checkLuhn 函数独立出来,有助于代码的复用和维护。

7. 总结

通过本文的教程,您应该已经掌握了如何在前端表单中有效地集成自定义验证逻辑。利用 HTML5 的原生验证能力与 JavaScript 的 setCustomValidity() 方法,我们可以为用户提供一个既强大又用户友好的表单验证体验。无论是简单的必填项检查,还是复杂的 Luhn 算法校验,这种结合方式都能帮助您构建出更加健壮和可靠的 Web 表单。请记住,客户端验证是用户体验的基石,而服务器端验证则是数据安全的最后防线,两者缺一不可。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

559

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

437

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

776

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

479

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

554

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

1091

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

659

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

554

2023.09.20

edge浏览器怎样设置主页 edge浏览器自定义设置教程
edge浏览器怎样设置主页 edge浏览器自定义设置教程

在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

0

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

CSS教程
CSS教程

共754课时 | 23.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号