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

Express服务接收前端搜索关键词为undefined的问题求助

问题:MERN栈搜索帖子时前端关键词在后端变为undefined

开发基于MERN栈的React社交应用,后端用Node.js+Express+Mongoose,前后端通过Axios+Redux Thunk交互。实现关键词搜索帖子的GET请求时,前端发送的关键词到后端后显示undefined,无法正常执行搜索逻辑。

核心问题分析及修复方案

1. GET请求参数传递方式错误

Axios的GET方法第二个参数是配置对象,不是请求体。直接传递keyword作为第二个参数,Axios不会将其纳入请求,导致后端接收不到。且GET请求规范做法是将参数放到URL查询参数中。

修改前端API代码:

export const getPostsByKeyword = (keyword, page) =>
  API.get(`/post/getPostsByKey`, {
    params: {
      page,
      keyword // 将关键词放入查询参数
    }
  });

2. 后端获取参数的方式错误

后端当前从req.body.keyword获取关键词,但GET请求默认不解析请求体,且前端未正确传递body数据。需改为从查询参数req.query.keyword获取,同时处理关键词为空的边界情况,避免正则表达式报错。

修改后端控制器代码:

export const getPosts = catchAsync(async (req, res, next) => {
  const data = req.query.keyword || ""; // 处理关键词为空的默认情况
  const page = parseInt(req.query.page || "0");
  const PAGE_SIZE = 20;
  const query = new RegExp(data, "i");
  
  // 统计总数时要匹配搜索条件,而非所有帖子
  const total = await Post.countDocuments({ $or: [{ title: query }, { content: query }] });
  const posts = await Post.find({ $or: [{ title: query }, { content: query }] })
    .limit(PAGE_SIZE)
    .skip(PAGE_SIZE * page);

  // 空数组不是falsy,需判断长度
  if (posts.length === 0) {
    return next(new ErrorHandlng("No posts were found", 400));
  }

  res.status(200).json({
    status: "success",
    data: {
      totalPages: Math.ceil(total / PAGE_SIZE),
      posts,
    },
  });
});

3. 后端控制器冗余代码问题

控制器中不应重复创建Express实例(const app = express()),也不应在控制器内配置中间件。这些配置需放到项目主入口文件(如server.js)中,控制器仅负责处理请求逻辑。

主入口文件示例(server.js):

import express from "express";
const app = express();
import bodyParser from "body-parser";
import postRoutes from "./routes/postRoutes.js"; // 路由文件路径

// 配置中间件
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 挂载路由
app.use("/post", postRoutes);

// 启动服务
const PORT = 8000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

4. Redux Thunk错误处理优化

  • response.statusCode是数字类型,判断时需用response.status === 400
  • response.data已是Axios解析后的JSON,无需await
  • 捕获错误时返回rejectWithValue,让Redux能处理错误状态
  • 补充extraReducers处理异步请求的状态变化

修改Post切片代码:

export const fetchPostsByKeyWord = createAsyncThunk(
  "post/getKeyword",
  async ({ keyword, page }, { fulfillWithValue, rejectWithValue }) => {
    try {
      const response = await api.getPostsByKeyword(keyword, page);
      if (response.status === 400) {
        throw new Error("There are no available posts");
      }
      const fetchData = response.data.data.posts;
      const totalPages = response.data.data.totalPages;
      return fulfillWithValue({ fetchData, totalPages });
    } catch (err) {
      const errorMsg = err.message || err.response?.data?.message || "Failed to fetch posts";
      console.log(errorMsg);
      return rejectWithValue(errorMsg);
    }
  }
);

const initialState = {
  status: "idle",
  posts: [],
  totalPages: 0,
  error: null
};

const PostSlice = createSlice({
  name: "post",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchPostsByKeyWord.pending, (state) => {
        state.status = "loading";
        state.error = null;
      })
      .addCase(fetchPostsByKeyWord.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.posts = action.payload.fetchData;
        state.totalPages = action.payload.totalPages;
      })
      .addCase(fetchPostsByKeyWord.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload;
      });
  },
});

export const postActions = PostSlice.actions;
export default PostSlice;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:35:24