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

如何通过AJAX接口检测MongoDB Schema中用户名是否已存在

注册表单用户名实时查重功能故障排查与修复

问题描述

开发注册表单时,希望实现用户输入用户名时实时检查MongoDB中该用户名是否已存在,但当前功能无法正常运行。

现有代码

表单HTML代码

<form class="needs-validation" action="/register" method="POST" novalidate>
  <div class="text-center mb-3">
    <p class="lead">Welcome to the team! We just need a few things to get started.</p>
    <div class="row">
      <div class="col-md-6 mb-4">
        <div class="form-outline">
          <input
                 type="text"
                 id="first_name"
                 name="first_name"
                 class="form-control"
                 required
                 />
          <label class="form-label" for="first_name"
                 >First name</label
            >
          <div class="valid-feedback">Looks good!</div>
          <div class="invalid-feedback">Thats not right</div>
        </div>
      </div>
      <div class="col-md-6 mb-4">
        <div class="form-outline">
          <input
                 type="text"
                 id="last-name"
                 name="last-name"
                 class="form-control"
                 required
                 />
          <label class="form-label" for="last-name"
                 >Last name</label
            >
          <div class="valid-feedback">Looks good!</div>
          <div class="invalid-feedback">Thats not right</div>
        </div>
      </div>
    </div>

  <!-- Email input -->
  <div class="form-outline mb-4">
    <input
           type="email"
           id="register_email"
           name="register_email"
           class="form-control"
           required
           />
    <label class="form-label" for="register_email">Email</label>
    <div class="valid-feedback">Looks good!</div>
    <div class="invalid-feedback">Thats not right</div>
  </div>
  <div class="text-center mb-3">
      <div class="form-outline mb-4">
        <input type="text" id="register_username" name="register_username" class="form-control" placeholder="enter your username" required />
        <label class="form-label" for="register_username">Username</label>
        <div id="username-check"></div>
      </div>
      <!-- Password input -->
      <div class="form-outline mb-4">
        <input type="password"  id="register_password" name="register_password" class="form-control" required/>
        <label class="form-label" for="register_password">Password</label>
        
        
      </div>
  </div>
  <!-- Submit button -->
  <div class="text-center">
      <button type="submit" id="register" class="btn btn-lg btn-rounded bg-insider link-dark mb-3 fw-bold" disabled>
    Lets Go! <i class="fa-solid fa-gauge-max"></i>
  </button>
  </div>
  
</form>

前端AJAX脚本

$('#register_username').on('keyup', function () {
  $.get('/usercheck?username=' + $(this).val().toLowerCase(), function (response) {
    $('#username-check').text(response.message);
    console.log('')
    var btn = document.getElementById('register');
    btn.disabled = true;

    if ($('#username-check').html() === "user exists") {
      $('#username-check').text('username not available').css('color', 'red');
    }
    else {
      console.log($('#register_username').val())
      $('#username-check').text('username is available').css('color', 'green');
        btn.disabled = false;
      
    }
  })
});

后端Express路由代码

var express     =   require("express"),
    router      =   express.Router(),
    passport    =   require("passport"),
    User        =   require("../models/user");

router.get('/usercheck', function(req, res) {
    console.log(req.query);
    User.findOne({username: req.query.register_username}, function(err, username){
        if(err) {
          console.log(err);
        }
        var message;
        if(username) {
          console.log(username);
            message = "user exists";
            console.log(message);
        } else {
            message= "user doesn't exist";
            console.log(message);
        }
        res.json({message: message});
    });
});
module.exports = router;

MongoDB User Schema代码

var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");

var UserSchema = new mongoose.Schema({
   username: String,
   password: String,
   email: String,
   isAdmin: { type: Boolean, default: false }
});

UserSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("User",UserSchema);

问题排查

  1. 后端参数获取错误:前端AJAX请求传递的查询参数是username,但后端路由错误使用req.query.register_username获取参数,导致查询条件为空,无法匹配数据库中的用户名。
  2. 前端逻辑冗余且易出错:先将后端返回消息写入DOM,再读取DOM内容判断,不仅冗余,还可能因DOM渲染延迟导致判断错误;应直接使用后端返回的response.message做逻辑判断。
  3. 错误处理缺失:后端findOne回调仅打印错误,未返回错误响应给前端;前端AJAX也未处理请求失败的情况。
  4. 大小写一致性问题:前端将用户名转为小写发送,但数据库中用户名可能大小写混合,未统一处理会导致查重结果不准确。

修复方案

修正后端路由代码

var express     =   require("express"),
    router      =   express.Router(),
    passport    =   require("passport"),
    User        =   require("../models/user");

router.get('/usercheck', function(req, res) {
    console.log(req.query);
    // 修复:使用正确的查询参数username
    User.findOne({username: req.query.username}, function(err, foundUser){
        if(err) {
          console.log(err);
          // 新增:返回服务器错误响应
          return res.status(500).json({message: "服务器错误"});
        }
        var message;
        if(foundUser) {
          console.log(foundUser);
            message = "user exists";
            console.log(message);
        } else {
            message= "user doesn't exist";
            console.log(message);
        }
        res.json({message: message});
    });
});
module.exports = router;

修正前端AJAX脚本

$('#register_username').on('keyup', function () {
  const username = $(this).val().toLowerCase();
  // 新增:避免空输入时发送请求
  if (!username.trim()) {
    $('#username-check').text('');
    $('#register').prop('disabled', true);
    return;
  }
  
  $.get('/usercheck?username=' + username, function (response) {
    const btn = $('#register');
    // 修复:直接使用后端返回的response.message判断,避免依赖DOM
    if (response.message === "user exists") {
      $('#username-check').text('用户名不可用').css('color', 'red');
      btn.prop('disabled', true);
    } else {
      $('#username-check').text('用户名可用').css('color', 'green');
      btn.prop('disabled', false);
    }
  })
  // 新增:处理AJAX请求失败的情况
  .fail(function() {
    $('#username-check').text('检查失败,请稍后重试').css('color', 'orange');
    $('#register').prop('disabled', true);
  });
});

优化User Schema(可选)

为确保用户名唯一性并统一大小写,可在Schema中添加配置:

var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");

var UserSchema = new mongoose.Schema({
   username: { 
     type: String, 
     unique: true, 
     required: true,
     // 新增:自动将用户名转为小写存储,确保查重不区分大小写
     lowercase: true
   },
   password: String,
   email: String,
   isAdmin: { type: Boolean, default: false }
});

UserSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("User",UserSchema);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:05:25