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 === 400response.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
相关产品推荐
相关产品推荐

