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

Next.js+Axios SSR页面控制台报404但数据正常获取求助

问题分析与解决方案

核心问题根源

  1. 未捕获的Axios请求异常:你的getServerSideProps里没对Axios请求做错误捕获,当请求触发404时,异常直接抛出,导致Next.js在客户端弹出"Failed to load static props"错误。你能正常拿到数据,大概率是Next.js内部对请求做了重试,最终请求成功,但重试过程拖慢了页面加载速度。
  2. API URL拼接的潜在问题:用req.url拼接API地址可能引入无效路径,比如页面URL含特殊字符、重复路径或后端未定义的路由时,就会触发404。另外,服务端请求本地API用完整http://localhost:3000地址,会多一次网络请求,这也是加载慢的原因之一。

具体修复步骤

1. 添加错误捕获逻辑

在getServerSideProps里用try/catch包裹Axios请求,捕获并处理异常,避免未捕获错误导致的客户端提示和重试:

export const getServerSideProps: GetServerSideProps = async ({ req }) => {
  try {
    const apiURL = `http://localhost:3000/api${req.url}`;
    const { data } = await axios.get(apiURL);

    if (!data?.data) { // 更严谨的空值检查,确保数据结构符合预期
      return { notFound: true };
    }

    return {
      props: {
        results: data.data,
      }
    };
  } catch (error) {
    // 打印详细错误信息,方便定位问题
    console.error("API请求失败详情:", error.response?.data || error.message);
    // 根据错误类型返回对应结果
    if (error.response?.status === 404) {
      return { notFound: true };
    }
    // 其他错误返回默认数据,避免页面渲染崩溃
    return {
      props: { results: { stuff: [] } }
    };
  }
};

2. 优化API请求方式(可选但推荐)

服务端请求本地Next.js API路由时,无需通过HTTP请求,直接导入API路由的处理函数调用,减少网络开销,提升加载速度:
假设你的API路由文件是pages/api/[...path].ts(匹配所有路径),可以这样调用:

import { handler as apiHandler } from "../api/[...path]";

export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
  try {
    // 模拟API路由的请求处理流程
    await new Promise((resolve, reject) => {
      apiHandler(req, res, (err) => {
        if (err) reject(err);
        else resolve(null);
      });
    });

    // 从res中获取API返回的数据(需要在API路由里把数据挂载到res.locals)
    const data = res.locals.apiData;

    if (!data) {
      return { notFound: true };
    }

    return { props: { results: data } };
  } catch (error) {
    console.error("API调用失败:", error);
    return { props: { results: { stuff: [] } } };
  }
};

注意:这种方式需要修改你的API路由,将返回数据挂载到res.locals上,避免直接发送HTTP响应(服务端渲染时不需要真正返回响应)。

3. 验证API URL的正确性

在try块里先打印apiURL,确认每次请求的地址是否符合后端路由:

console.log("当前API请求地址:", apiURL);

如果发现URL有问题(比如重复的/、多余参数),可以对req.url做清洗处理:

// 确保路径格式正确,避免出现/api//xxx这类无效地址
const cleanUrl = req.url.startsWith('/') ? req.url : `/${req.url}`;
const apiURL = `http://localhost:3000/api${cleanUrl}`;

额外优化建议

  • 给Axios请求添加超时时间,避免长时间等待拖慢页面:
const { data } = await axios.get(apiURL, { timeout: 5000 }); // 设置5秒超时
  • 如果API数据允许缓存,可考虑用getStaticProps结合增量静态生成(ISR)替代getServerSideProps,进一步提升加载速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:50:11