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,提问作者박근영
相关产品推荐
相关产品推荐

