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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:02:40