Axios请求返回404错误,预期应为401未授权问题排查
问题:Axios请求返回404而非预期的401未授权状态码
在React项目的home.jsx中使用Axios发送GET请求,尝试从连接MongoDB的Express服务器获取数据,但收到以下404错误:
"AxiosError {message: 'Request failed with status code 404', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}"
预期应该返回401未授权状态码,相关代码如下:
home.jsx代码
import Navbar from "../../navbar/Navbar"; import Featured from "../../featured/Featured"; import "./home.scss"; import List from "../../list/List"; import { useState, useEffect } from "react"; import axios from "axios"; const Home = ({ type }) => { const [lists, setLists] = useState([]); const [genre, setGenre] = useState(null); useEffect(() => { const getRandomLists = async () => { try { const res = await axios.get( `lists/${type ? "?type=" + type : ""}&${genre ? "&genre=" + genre: ""}` ); console.log(res) // setLists(res.data); } catch (err) { console.log(err); } }; getRandomLists(); }, [type, genre]); return ( <div className="home"> <Navbar /> <Featured type={type} /> <List /> <List /> <List /> <List /> </div> ); }; export default Home;
Express的lists路由代码
//GET router.get("/", verify, async (req, res) => { const typeQuery = req.query.type; const genreQuery = req.query.genre; let list = []; try { if (typeQuery) { if (genreQuery) { list = await List.aggregate([ { $sample: { size: 10 } }, { $match: { type: typeQuery, genre: genreQuery } }, ]); } else { list = await List.aggregate([ { $sample: { size: 10 } }, { $match: { type: typeQuery } }, ]); } } else { list = await List.aggregate([{ $sample: { size: 10 } }]); } res.status(200).json(list); } catch (err) { res.status(500).json(err); } }); module.exports = router;
解决方案
1. 404错误的核心原因
- 请求路径不匹配:React中Axios用的是相对路径
lists/...,会拼接当前前端页面URL,导致请求没发到Express服务器的正确路由上。 - URL拼接语法错误:当
type为空时,URL会变成lists/&genre=xxx,无效格式会进一步导致路径异常。 - 因为请求根本没到达带
verify中间件的Express路由,所以不会返回预期的401。
2. 修复步骤
步骤一:修正Axios请求路径与参数拼接
用Axios的baseURL配置确保请求指向服务器,同时用params自动处理参数拼接,避免手动拼接的错误:
// 在组件内或全局配置Axios基础URL,替换为你的Express服务器地址 const axiosInstance = axios.create({ baseURL: "http://localhost:5000/api" // 假设Express端口为5000,lists路由挂载在/api下 }); // 正确构建查询参数 const getRandomLists = async () => { try { const params = {}; if (type) params.type = type; if (genre) params.genre = genre; const res = await axiosInstance.get("/lists", { params }); console.log(res); // setLists(res.data); } catch (err) { console.log(err); } };
步骤二:确认Express路由挂载位置
检查Express主文件(如app.js/server.js),确保lists路由的挂载前缀和前端请求路径对应:
const listsRouter = require("./routes/lists"); // 这里的前缀要和前端baseURL后的路径一致 app.use("/api/lists", listsRouter);
如果路由直接挂载在根路径/lists,则前端baseURL设为http://localhost:5000,请求路径为/lists。
步骤三:验证verify中间件有效性
路径修复后,若仍未返回401,检查verify中间件实现:
- 确保未授权时返回
res.status(401).json({ message: "未授权" }) - 确认中间件没有因路由配置问题被跳过
3. 额外排查建议
- 用
morgan日志中间件查看Express接收到的请求路径和状态码:const morgan = require('morgan'); app.use(morgan('dev')); - 在前端控制台查看请求的完整URL,确认是否与Express路由匹配。
内容的提问来源于stack exchange,提问作者Abdul Waris
相关产品推荐
相关产品推荐

