使用getServerSideProps时如何将/_next/data前缀修改为/login/_next/data
Next.js修改getServerSideProps生产环境数据请求前缀方案
getServerSideProps是Next.js Pages Router下的服务端渲染数据获取能力,生产环境客户端路由跳转时默认会请求/_next/data/[buildId]/[route].json获取页面props,修改前缀分两种场景处理:
方案一:全局子路径部署(官方推荐,无兼容问题)
如果你的应用本身就需要部署在/login子路径下,直接使用Next.js原生提供的basePath配置即可,不需要额外写业务逻辑,所有内部请求(包含_next/data数据请求、静态资源、路由跳转)都会自动带上/login前缀。
配置方式:
- 打开项目根目录的
next.config.js,添加如下配置:
/** @type {import('next').NextConfig} */ const nextConfig = { basePath: '/login', } module.exports = nextConfig
- 重新执行构建、启动服务即可生效,后续所有
/_next/data/**的请求会自动替换为/login/_next/data/**。
注意:配置
basePath后,所有页面路由访问也会自动带上/login前缀,比如原/home路由需要通过/login/home访问,适合应用整体部署在子路径的场景。
方案二:仅修改data请求前缀(特殊场景hack)
如果你不需要给全局路由加/login前缀,只需要把getServerSideProps的数据请求前缀改成/login/_next/data(比如需要单独给数据请求加鉴权网关),可以通过「客户端请求拦截+服务端路由重写」实现:
- 第一步:客户端拦截fetch请求,替换默认的data请求前缀
在pages/_app.js/pages/_app.tsx中添加全局fetch拦截逻辑:
import { useEffect } from 'react' function MyApp({ Component, pageProps }) { useEffect(() => { const originFetch = window.fetch window.fetch = (resource, options) => { let requestUrl = typeof resource === 'string' ? resource : resource.url // 替换默认_next/data前缀 if (requestUrl.startsWith('/_next/data/')) { requestUrl = requestUrl.replace('/_next/data/', '/login/_next/data/') resource = typeof resource === 'string' ? requestUrl : new Request(requestUrl, resource) } return originFetch.call(window, resource, options) } return () => { window.fetch = originFetch } }, []) return <Component {...pageProps} /> } export default MyApp
- 第二步:服务端重写路径,交给Next.js原生逻辑处理
如果使用自定义Node服务启动Next.js(比如Express),添加路由重写规则,把/login/_next/data的请求转回内部的/_next/data路径:
const express = require('express') const next = require('next') const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { const server = express() // 拦截data请求,重写路径 server.get('/login/_next/data/*', (req, res) => { req.url = req.url.replace('/login/_next/data/', '/_next/data/') return handle(req, res) }) // 其余请求走默认处理逻辑 server.all('*', (req, res) => handle(req, res)) server.listen(3000) })
如果是用Nginx等反向代理部署,也可以直接在Nginx配置中加重写规则:
location /login/_next/data/ { rewrite ^/login(/_next/data/.*)$ $1 break; proxy_pass http://你的nextjs服务地址; }
注意:该方案属于非官方hack实现,Next.js大版本升级时可能因为内部请求逻辑变化失效,升级后需要做针对性验证。
不推荐的做法
- 直接修改
node_modules中Next.js的源码:依赖重装、版本升级后配置会直接丢失,还可能引发其他不可预期的运行错误。 - 仅配置反向代理重写,不修改客户端请求前缀:客户端路由跳转时还是会默认请求
/_next/data路径,直接报404错误。
内容的提问来源于stack exchange,提问作者jjerrycai
相关产品推荐
相关产品推荐

