
本文档旨在提供一个清晰的指南,说明如何使用 Luhn 算法在 HTML 表单中验证信用卡号码。通过结合 JavaScript 和 HTML5 的表单验证功能,我们将创建一个用户友好的表单,该表单可以实时检查信用卡号码的有效性,并在号码无效时提供反馈。本文档包含完整的代码示例,以及对代码的详细解释,帮助开发者轻松地将此功能集成到自己的项目中。
Luhn 算法简介
Luhn 算法,也称为模 10 算法,是一种简单的校验和公式,用于验证各种识别号码,如信用卡号码、IMEI 号码等。该算法可以检测出常见的输入错误,例如单个数字的错误输入或相邻数字的换位。
实现步骤
以下步骤将指导您完成使用 Luhn 算法验证信用卡号码的整个过程:
- HTML 表单结构:
首先,我们需要创建一个包含信用卡号码输入字段的 HTML 表单。重要的是,该字段应具有唯一的 ID,以便我们可以使用 JavaScript 访问它。同时,添加必要的反馈元素,以便在验证失败时向用户显示错误消息。
Please provide your credit card number.Please provide a valid credit card number.
- JavaScript 代码:
a. 获取输入字段:
使用 document.querySelector() 方法获取信用卡号码输入字段的引用。
b. 绑定输入事件:
使用 $('#cc').on('input', function(){ ... }); 监听输入字段的 input 事件。每次用户在输入字段中输入内容时,都会触发此事件。
c. Luhn 算法验证:
在事件处理程序中,调用 checkLuhn() 函数来验证信用卡号码。
d. 设置自定义有效性:
根据 checkLuhn() 函数的结果,使用 field.setCustomValidity() 方法设置输入字段的自定义有效性。如果号码有效,则将自定义有效性设置为空字符串(""),否则设置为错误消息(例如 "Invalid field.")。
$('#cc').on('input', function(){
const field = document.querySelector('#cardContainer input')
if (checkLuhn($('#cc').val())) {
field.setCustomValidity("");
} else {
field.setCustomValidity("Invalid field.");
}
});
function checkLuhn(value) {
// accept only digits, dashes or spaces
if (/[^0-9-\s]+/.test(value)) return false;
// The Luhn Algorithm. It's so pretty.
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}- CSS 样式:
使用 CSS 样式来显示或隐藏错误消息,并根据验证结果更改输入字段的边框颜色。
.invalid-feedback,
.empty-feedback {
display: none;
}
.was-validated :placeholder-shown:invalid ~ .empty-feedback {
display: block;
}
.was-validated :not(:placeholder-shown):invalid ~ .invalid-feedback {
display: block;
}
.is-invalid,
.was-validated :invalid {
border-color: #dc3545;
}- 完整代码:
Contact Us
Fill up the form below to send us a message.
(function () {
"use strict";
/*
* Form Validation
*/
// Fetch all the forms we want to apply custom validation styles to
const forms = document.querySelectorAll(".needs-validation");
const result = document.getElementById("result");
// Loop over them and prevent submission
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener(
"submit",
function (event) {
if (!form.checkValidity() ) {
event.preventDefault();
event.stopPropagation();
form.querySelectorAll(":invalid")[0].focus();
} else {
/*
* Form Submission using fetch()
*/
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");
},
false
);
});
})();
$('#cc').on('input', function(){
const field = document.querySelector('#cardContainer input')
if (checkLuhn($('#cc').val())) {
field.setCustomValidity("");
} else {
field.setCustomValidity("Invalid field.");
}
});
function checkLuhn(value) {
// accept only digits, dashes or spaces
if (/[^0-9-\s]+/.test(value)) return false;
// The Luhn Algorithm. It's so pretty.
var nCheck = 0, nDigit = 0, bEven = false;
value = value.replace(/\D/g, "");
for (var n = value.length - 1; n >= 0; n--) {
var cDigit = value.charAt(n),
nDigit = parseInt(cDigit, 10);
if (bEven) {
if ((nDigit *= 2) > 9) nDigit -= 9;
}
nCheck += nDigit;
bEven = !bEven;
}
return (nCheck % 10) == 0;
}.invalid-feedback,
.empty-feedback {
display: none;
}
.was-validated :placeholder-shown:invalid ~ .empty-feedback {
display: block;
}
.was-validated :not(:placeholder-shown):invalid ~ .invalid-feedback {
display: block;
}
.is-invalid,
.was-validated :invalid {
border-color: #dc3545;
}注意事项
- 安全性: 此代码仅用于客户端验证。为了确保安全性,您仍然需要在服务器端执行验证。
- 用户体验: 考虑添加额外的用户体验功能,例如在用户输入时格式化信用卡号码。
- 兼容性: 确保您的代码在所有目标浏览器中都能正常工作。
总结
通过结合 HTML 表单、JavaScript 和 Luhn 算法,我们可以创建一个用户友好的表单,该表单可以实时验证信用卡号码的有效性。这可以帮助减少输入错误,并提高用户体验。请记住,客户端验证只是安全措施的一部分,您仍然需要在服务器端执行验证。











