Next.js getServerSideProps的context.req.url返回异常路径如何解决?
问题根因
- 该路径属于Next.js的客户端路由数据预取请求地址,是框架的正常行为:
- 用户直接刷新页面、从地址栏输入路径访问时,
context.req.url为预期的页面路由地址 - 用户通过
<Link>组件、router.push等客户端API跳转页面时,Next.js不会请求完整HTML,只会请求对应页面getServerSideProps返回的JSON数据,此时请求路径自动生成/_next/data/[环境]/[locale]/[页面名].json格式
- 用户直接刷新页面、从地址栏输入路径访问时,
- 依赖
context.req.url的业务逻辑本身不可靠,该字段是原始HTTP请求路径,会随访问场景不同发生格式变化,不适合作为业务逻辑的判断依据
修复方案
推荐方案:替换为context.resolvedUrl
Next.js已经在GetServerSidePropsContext中封装了标准化的路由地址字段resolvedUrl,无论访问场景是什么,都会返回统一格式的页面路由,不会携带/_next/data前缀,直接替换即可:
export function getServerSidePropsWithPageInitData(options: PropsOptions = {}) { return wrapper.getServerSideProps((store) => { const { getState, dispatch } = store; return async function(context: GetServerSidePropsContext) { // 替换context.req.url为context.resolvedUrl console.log({ url: context.resolvedUrl }) return await getPageInitialData(serverContext); }; }) }
备选方案:手动拼接路由
如果需要自定义路由拼接逻辑,可以用context自带的pathname和query参数组装:
const queryStr = new URLSearchParams(context.query as Record<string, string>).toString() const fullPath = queryStr ? `${context.pathname}?${queryStr}` : context.pathname
扩展需求:获取完整带域名的URL
如果业务需要完整的带协议、域名的URL,可以通过请求头拼接:
const protocol = context.req.headers['x-forwarded-proto'] ?? 'http' const fullUrl = `${protocol}://${context.req.headers.host}${context.resolvedUrl}`
内容的提问来源于stack exchange,提问作者Ascolon
相关产品推荐
相关产品推荐

