You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript登录表单异常:输入错误凭据仍可登录的问题排查求助

原生JS注册登录功能问题排查

我基于原生JavaScript实现了一套带表单验证的注册登录功能,采用简单的内存存储已注册用户,仅用于学习用途。该程序要求用户注册时输入自定义用户名(需唯一、长度3-15位)、有效邮箱、8-20位密码且需确认密码一致;注册完成后可使用注册凭据登录。

问题描述

目前遇到的问题是:即使输入未注册邮箱、错误邮箱或错误密码,用户仍能登录。请问该问题是否出在validateLogin()函数中?

原代码

const registeredUsers = [];

const loginForm = document.getElementById('loginForm');

loginForm.addEventListener('submit', (e) => {
    e.preventDefault();
    validateRegistration();
    validateLogin();
});

function validateRegistration() {
    const username = document.getElementById("username").value;
    const email = document.getElementById("email").value;
    const password = document.getElementById("password").value;
    const confirmPassword = document.getElementById("confirmPassword").value;

    if (username.length < 3 || username.length > 15) {
        alert("Username must be between 3 and 15 characters.");
        return;
    }

    if (registeredUsers.some(user => user.username === username)) {
        alert("Username already taken. Please choose another one.");
        return;
    }

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
        alert("Invalid email address.");
        return;
    }

    if (registeredUsers.some(user => user.email === email)) {
        alert("Email address already registered.");
        return;
    }

    if (password.length < 8 || password.length > 20) {
        alert("Password must be between 8 and 20 characters.");
        return;
    }

    if (password !== confirmPassword) {
        alert("Passwords do not match.");
        return;
    }

    registeredUsers.push({ username, email, password });
    alert("Registration successful!");
}

function validateLogin() {
    const email = document.getElementById("email").value;
    const password = document.getElementById("password").value;

    // Find user by email
    const user = registeredUsers.find(user => user.email === email);

    if (user) {
        // User found, now check the password
        if (user.password === password) {
            alert("Welcome " + user.username + "!");
        } else {
            alert("Invalid password. Please try again.");
        }
    } else {
        alert("Invalid email. Please try again or register.");
    }
}

问题根源

不是validateLogin()的问题,核心bug在表单提交事件的逻辑绑定上:你把注册验证和登录验证同时绑定到了同一个表单的提交事件中。

当用户尝试登录时,提交表单会先执行validateRegistration()——如果用户输入的信息刚好符合注册规则(比如用户名长度合规、邮箱格式正确、密码和确认密码一致),即使这个邮箱原本未注册,validateRegistration()也会直接把该用户添加到registeredUsers数组里,紧接着执行的validateLogin()就会找到刚注册的用户,判定登录成功。

这就导致用户输入未注册邮箱时,反而自动完成注册并登录,完全违背了登录功能的预期逻辑。

解决方案

  1. 拆分注册与登录表单:分别创建独立的注册表单和登录表单,避免字段混用。
  2. 分离事件绑定:给两个表单各自绑定对应的验证逻辑,注册表单仅触发注册验证,登录表单仅触发登录验证。
  3. 优化字段ID:登录表单的邮箱、密码字段使用独立ID,避免与注册表单字段冲突。

修改后的完整代码

HTML部分

<!-- 注册表单 -->
<form id="registerForm">
  <input type="text" id="username" placeholder="用户名(3-15位)">
  <input type="email" id="registerEmail" placeholder="邮箱">
  <input type="password" id="registerPassword" placeholder="密码(8-20位)">
  <input type="password" id="confirmPassword" placeholder="确认密码">
  <button type="submit">注册</button>
</form>

<!-- 登录表单 -->
<form id="loginForm">
  <input type="email" id="loginEmail" placeholder="邮箱">
  <input type="password" id="loginPassword" placeholder="密码">
  <button type="submit">登录</button>
</form>

JavaScript部分

const registeredUsers = [];

// 注册表单提交事件
const registerForm = document.getElementById('registerForm');
registerForm.addEventListener('submit', (e) => {
    e.preventDefault();
    validateRegistration();
});

// 登录表单提交事件
const loginForm = document.getElementById('loginForm');
loginForm.addEventListener('submit', (e) => {
    e.preventDefault();
    validateLogin();
});

function validateRegistration() {
    const username = document.getElementById("username").value;
    const email = document.getElementById("registerEmail").value;
    const password = document.getElementById("registerPassword").value;
    const confirmPassword = document.getElementById("confirmPassword").value;

    if (username.length < 3 || username.length > 15) {
        alert("用户名长度必须在3-15位之间。");
        return;
    }

    if (registeredUsers.some(user => user.username === username)) {
        alert("该用户名已被占用,请更换。");
        return;
    }

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
        alert("邮箱格式无效。");
        return;
    }

    if (registeredUsers.some(user => user.email === email)) {
        alert("该邮箱已注册,请直接登录。");
        return;
    }

    if (password.length < 8 || password.length > 20) {
        alert("密码长度必须在8-20位之间。");
        return;
    }

    if (password !== confirmPassword) {
        alert("两次输入的密码不一致。");
        return;
    }

    registeredUsers.push({ username, email, password });
    alert("注册成功!请登录。");
    registerForm.reset();
}

function validateLogin() {
    const email = document.getElementById("loginEmail").value;
    const password = document.getElementById("loginPassword").value;

    const user = registeredUsers.find(user => user.email === email);

    if (user) {
        if (user.password === password) {
            alert("欢迎回来," + user.username + "!");
            loginForm.reset();
        } else {
            alert("密码错误,请重试。");
        }
    } else {
        alert("该邮箱未注册,请先完成注册。");
    }
}

内容的提问来源于stack exchange,提问作者Liyanna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:44:51