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

MERN栈CRUD应用搜索功能报BSONTypeError错误求解决

问题原因

你遇到的BSONTypeError是因为Express路由匹配顺序引发的冲突:

  • 服务端先定义了app.get('/user/:id')路由,该路由会匹配所有/user/xxx格式的请求,包括你搜索用户时发送的/user/用户名请求。
  • 当搜索请求进入时,Express会把用户名当作id参数传入该路由,随后执行ObjectId(updateId)——但用户名并非合法的MongoDB ObjectId(要求是12字节字符串、24位十六进制字符串或整数),因此抛出错误。
  • 你定义的app.get('/user/:name')路由永远不会被触发,因为前面的/:id路由已经优先匹配了所有请求。
解决方案

推荐使用查询参数实现搜索功能,彻底避免路由冲突,同时让接口设计更规范:

1. 修改客户端代码(Search.js)

将请求URL改为带查询参数的格式:

import React from 'react';

const Search = () => {

    const searchHandle = e => {
        e.preventDefault();

        const userName = e.target.search.value;
        // 修改为查询参数格式的请求URL
        fetch(`http://localhost:5000/user/search?name=${userName}`)
        .then(res => res.json())
        .then(data => console.log(data))
        .catch(err => console.log(err));

        console.log(typeof(userName));
    }

    return (
        <div className='px-3 py-2 w-3/4'>
            <h1 className='text-3xl font-bold mb-3'>Search User:</h1>
            <form onSubmit={searchHandle}>
                <input className='bg-gray-200 rounded p-2 w-3/4' type="search" name="search" id="name" />
                <button className='bg-blue-500 mx-2 py-2 px-4 rounded' type='submit'>Search</button>
            </form>
        </div>
    );
}

export default Search;

2. 修改服务端代码

  • 删除原有的app.get('/user/:name')路由
  • 添加新的搜索路由,通过查询参数获取关键词并实现MongoDB模糊查询:
const express = require('express'); // 修正拼写错误:expres → express
const cors = require('cors');
const { MongoClient, ServerApiVersion, ObjectId } = require('mongodb');


const app = express();
const port = process.env.PORT || 5000;


app.use(cors());
app.use(express.json())


const uri = "mongodb+srv://user:#@cluster0.moilkdv.mongodb.net/?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });

async function run() {
    try {
        const userCollection = client.db('simpleNode').collection('users');

        // 获取所有用户
        app.get('/user', async (req, res) => {
            const cursor = userCollection.find({});
            const users = await cursor.toArray();
            res.send(users);
        })

        // 获取单个用户用于更新
        app.get('/user/:id', async (req, res) => {
            const updateId = req.params.id;
            const updateQuery = { _id: ObjectId(updateId)}
            const user = await userCollection.findOne(updateQuery);
            res.send(user);
        })

        // 更新用户
        app.put('/user/:id', async (req, res) => {
            const userId = req.params.id;
            const user = req.body;
            const filter = { _id: ObjectId(userId) };
            const options = { upsert: true };
            const updatedUser = {
                $set: {
                    name: user.name,
                    address: user.address
                }
            }
            const result = await userCollection.updateOne(filter, updatedUser, options);
            res.send(result);
        })

        // 创建用户
        app.post('/user', async (req, res) => {
            console.log('post api called');
            const Nuser = req.body;
            const result = await userCollection.insertOne(Nuser);
            res.send(result);
        });

        // 新增:搜索用户(使用查询参数)
        app.get('/user/search', async (req, res) => {
            const searchName = req.query.name;
            // 模糊匹配,不区分大小写
            const searchQuery = { name: { $regex: searchName, $options: 'i' } };
            const matchedUsers = await userCollection.find(searchQuery).toArray();
            res.send(matchedUsers);
        })

        // 删除用户
        app.delete('/user/:id', async(req, res) => {
            const userId = req.params.id;
            const deleteQuery = { _id: ObjectId(userId)};
            const result = await userCollection.deleteOne(deleteQuery);
            console.log("Delete complete of: ", userId);
            console.log(result);
            res.send(result);
        })
    }
    finally {
    }
}

run().catch(console.dir);

app.get('/', (req, res) => {
    res.send('Server is running');
})


app.listen(port);

额外修正

服务端代码存在拼写错误:const expres = require('express');需改为const express = require('express');,否则会导致express模块无法正确加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:16:08