Next.js getServerSideProps未调用API返回403错误如何解决
问题根因
问题出在页面导出逻辑:你使用ProtectPage高阶组件包裹了Contacts页面组件,但HOC返回的新组件没有透传原组件上挂载的getServerSideProps静态方法。
Next.js在路由匹配时只会读取默认导出组件上的静态方法(getServerSideProps/getStaticProps等),识别不到被HOC遮挡的getServerSideProps时,会默认按静态页面逻辑处理,直接返回.next目录下预生成的JSON文件,根本不会执行你写的服务端数据拉取逻辑,自然不会发起业务API请求;静态资源请求被鉴权规则拦截时就会返回403 Unauthorized错误。
注:Next.js客户端路由跳转时请求/_next/data/development/xxx.json是框架默认行为,正常情况下该请求会触发服务端执行对应页面的getServerSideProps,将返回的props拼接为JSON响应,本身不是异常行为。
修复方案
二选一即可:
- 方案1:修改
ProtectPage高阶组件,透传被包裹组件的静态方法
手动透传示例:
如果项目里多个HOC都需要透传静态属性,可以引入const ProtectPage = (WrappedComponent) => { const ProtectedComp = (props) => { // 原有ProtectPage的鉴权逻辑 return <WrappedComponent {...props} /> } // 关键:手动透传getServerSideProps ProtectedComp.getServerSideProps = WrappedComponent.getServerSideProps // 若有其他Next.js静态方法(如getStaticProps)或自定义静态属性,也需要同步透传 return ProtectedComp }hoist-non-react-statics包自动完成静态属性复制,避免手动漏写。 - 方案2:移除页面外层的权限HOC,将鉴权逻辑迁移到
getServerSideProps内执行
服务端鉴权示例:export async function getServerSideProps(ctx) { // 从请求上下文ctx中读取cookie/token做登录态校验 const isAuthed = checkAuth(ctx.req) if (!isAuthed) { return { redirect: { destination: '/login', permanent: false } } } // 原有数据拉取逻辑 try { const contactsRes = await getContacts({}) const { data: initialContacts, pagination: initialPagination } = contactsRes.data return { props: { initialContacts, initialPagination } } } catch (error) { return { props: { initialContacts: [], initialPagination: {}, error: true } } } } // 直接导出原组件,无需HOC包裹 export default Contacts
验证方式
修复后重启Next.js开发服务,访问contacts页面时,服务端会正常执行getServerSideProps内的业务接口请求,/_next/data/development/contacts.json请求会返回包含正确props数据的响应,不再返回403错误。
内容的提问来源于stack exchange,提问作者MAE
相关产品推荐
相关产品推荐

