密码验证代码异常:为何未拦截不符合强度要求的密码?
密码强度验证失效的修复方案
问题背景
我编写了一段JavaScript代码,用于在用户提交表单前验证两次输入的密码是否一致,同时确保密码强度符合指定标准(至少6位,包含至少一个大写字母、一个小写字母、一个特殊字符和一个数字)。目前代码可正确拦截不一致的密码,但无法拦截长度过短或不满足正则表达式要求的密码。
原代码
JavaScript
const firstPass = document.querySelector("#firstPass"); const secondPass = document.querySelector("#secondPass"); const errorText = document.querySelector("#error-text"); const myButton = document.querySelector("#button"); let passwordStrength = false; /** 正则表达式要求密码至少6位,包含至少一个大写字母、一个小写字母、一个特殊字符和一个数字。 */ let regex = new RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?":{}|<>])(?=.*[0-9]).{6,}$'); // 检查密码是否符合要求 if (regex.test(firstPass.value)) { passwordStrength = true; } // 点击提交按钮时触发此函数 // 若密码不匹配,显示错误信息并阻止提交 // 否则显示成功信息并允许提交 myButton.onclick = function() { if (firstPass.value != secondPass.value) { errorText.style.display = "block"; errorText.classList.remove("matched"); errorText.textContent = "错误!两次输入的密码不匹配!"; return false; } else if (passwordStrength === false) { errorText.style.display = "block"; errorText.classList.remove("matched"); errorText.textContent = "密码长度至少6位,需包含特殊字符、大写和小写字母。"; return false; } else { errorText.style.display = "block"; errorText.classList.add("matched"); errorText.classList.remove("text-danger"); errorText.textContent = "密码匹配。"; return true; } };
HTML
<form action="protected/register.inc.php" method="post" autocomplete="off"> <p class="text-center">New Profile:</p> <!-- Name input --> <div class="form-outline mb-4"> <input type="text" id="registerName" class="form-control" name="registerName" /> <label class="form-label" for="registerName">First Name</label> </div> <!-- Username input --> <div class="form-outline mb-4"> <input type="text" id="registerLastName" class="form-control" name="registerLastName" /> <label class="form-label" for="registerLastName">Last Name</label> </div> <!-- Email input --> <div class="form-outline mb-4"> <input type="email" id="registerEmail" class="form-control" name="registerEmail" /> <label class="form-label" for="registerEmail">Email</label> </div> <!-- Password input --> <div class="form-outline mb-4"> <input type="password" id="firstPass" class="form-control" name="firstPass" /> <label class="form-label" for="firstPass">New Password</label> </div> <div id="error-text" class="text-danger"></div> <!-- Confirm password input --> <div class="form-outline mb-4"> <input type="password" id="secondPass" class="form-control" name="secondPass" /> <label class="form-label" for="secondPass">Repeat Password</label> </div> <!-- Submit button --> <button id="button" type="submit" class="btn btn-primary btn-block mb-3">Register</button> </form>
问题原因
密码强度的检查逻辑只在页面加载完成时执行了一次,此时输入框为空,passwordStrength被设置为false。后续用户输入密码时,这个变量不会自动更新,导致提交时始终用初始的false值判断,强度验证完全失效。
修复方案
将密码强度的检查逻辑移到提交按钮的点击事件内部,每次点击提交时都重新获取当前输入的密码并验证:
const firstPass = document.querySelector("#firstPass"); const secondPass = document.querySelector("#secondPass"); const errorText = document.querySelector("#error-text"); const myButton = document.querySelector("#button"); /** 正则表达式要求密码至少6位,包含至少一个大写字母、一个小写字母、一个特殊字符和一个数字。 */ let regex = new RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?":{}|<>])(?=.*[0-9]).{6,}$'); // 点击提交按钮时触发此函数 myButton.onclick = function() { // 每次提交时重新验证密码强度 const passwordStrength = regex.test(firstPass.value); if (firstPass.value != secondPass.value) { errorText.style.display = "block"; errorText.classList.remove("matched"); errorText.textContent = "错误!两次输入的密码不匹配!"; return false; } else if (!passwordStrength) { errorText.style.display = "block"; errorText.classList.remove("matched"); errorText.textContent = "密码长度至少6位,需包含特殊字符、大写和小写字母。"; return false; } else { errorText.style.display = "block"; errorText.classList.add("matched"); errorText.classList.remove("text-danger"); errorText.textContent = "密码匹配。"; return true; } };
额外优化建议
- 可以在用户输入密码时(比如监听
input事件)实时验证强度并提示,提升用户体验 - 注意正则表达式中的特殊字符转义,避免潜在的语法问题
内容的提问来源于stack exchange,提问作者Kyler England
相关产品推荐
相关产品推荐

