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

Next.js getServerSideProps重试时props返回undefined问题排查

问题排查与解决思路

首先,最可能的原因出在axios拦截器的错误处理逻辑上,尤其是token过期重试时的返回值处理:

  • 当你捕获到401错误并执行refreshToken流程后,一定要return重新发起请求的Promise。如果漏掉这个return,拦截器会默认返回undefined,哪怕你在拦截器里看到请求成功了,getServerSideProps拿到的结果还是undefined,最终导致客户端props里的serviceList为空。

举个正确的拦截器写法示例:

axiosInstance.interceptors.response.use(
  res => res,
  async err => {
    const originalReq = err.config;
    // 避免重复重试
    if (err.response.status === 401 && !originalReq._retry) {
      originalReq._retry = true;
      // 刷新token
      const newTokenData = await axiosInstance.post('/api/refresh-token', { refreshToken: xxx });
      // 更新实例的默认请求头
      axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${newTokenData.accessToken}`;
      // 关键:return重新发起的请求,把结果传递回getServerSideProps
      return axiosInstance(originalReq);
    }
    return Promise.reject(err);
  }
);

其次,检查getServerSideProps里的异步逻辑是否正确await:
确保你是用await等待axios请求完成,并且返回的props对象里确实正确携带了serviceList,比如:

export async function getServerSideProps() {
  try {
    const { data } = await axiosInstance.get('/api/service-list');
    console.log(data); // 这里能输出,说明请求成功
    return { props: { serviceList: data } }; // 确保这里的赋值没有问题
  } catch (err) {
    // 处理refreshToken也过期的情况,比如跳登录页
    return { redirect: { destination: '/login', permanent: false } };
  }
}

另外,排查是否存在竞态条件:
如果多个请求同时触发401,可能导致重复刷新token,后续重试请求拿到的token无效。给请求加_retry标记(像上面示例那样)可以避免这个问题。

最后,如果你用的是较旧的Next.js版本,也可以尝试升级到稳定版,排除框架本身的异步处理bug。

内容的提问来源于stack exchange,提问作者박근영

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:20:12