Nginx代理WordPress同站点Next.js页面静态资源404问题
两个核心配置问题导致静态资源404:
- Nginx location匹配优先级错误:配置末尾的静态资源缓存规则是正则匹配
~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$,正则location的优先级高于普通前缀匹配的location /_next,所有/_next路径下的css、js请求会先被这个静态规则拦截,直接去WordPress根目录/var/www/html下找文件,根本不会走到预先配置的Next.js反向代理逻辑。 - Next.js服务未配置子路径部署前缀:要把Next.js挂在
/specific-next-page子路径下,但默认Next.js生成的页面、静态资源引用路径都是从域名根路径开始的,就算代理通了/_next的请求,后续页面内跳转、资源引用也会出现路径不匹配问题。
第一步:调整Next.js配置,设置basePath
进入Next.js部署目录/var/www/next,找到next.config.js配置文件,添加basePath配置,和要挂载的子路径完全一致:
/** @type {import('next').NextConfig} */ const nextConfig = { // 原有配置全部保留 basePath: '/specific-next-page', // 建议同时关闭尾部斜杠自动匹配,避免不必要的重定向 trailingSlash: false, } module.exports = nextConfig
配置修改完成后重新构建Next.js服务并重启:
cd /var/www/next npm run build # 若使用pm2等进程管理工具,执行对应服务重启命令即可,例如pm2 restart next
添加basePath后,Next.js生成的所有静态资源引用路径会自动变为/specific-next-page/_next/...,页面内路由跳转也会自动带上子路径前缀,不会再跑到域名根路径找资源。
第二步:修正Nginx配置
首先删除原有配置中单独写的location /_next代理规则,因为配置basePath后静态资源路径已经归属到子路径下,之后调整两处逻辑:
- 给Next.js相关的location加
^~修饰符,提高匹配优先级,避免被后面的PHP解析规则、静态资源正则规则拦截 - 修正静态资源代理路径,直接代理子路径下的
_next请求到本地3000端口
用以下配置段替换原有# NEXT PROXY到# END NEXT之间的所有内容:
# NEXT PROXY location ^~ /specific-next-page/_next { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location ^~ /__nextjs_original-stack-frame { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # specific-page - next.js location ^~ /specific-next-page { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; } # END NEXT
原有配置中写的location /content代理规则如果不是Next.js业务必需,可以直接删除,避免路径冲突。
第三步:验证配置并重载Nginx
先执行配置校验命令,确认没有语法错误:
nginx -t
校验通过后重载Nginx使配置生效:
systemctl reload nginx
清空浏览器缓存后访问https://example.com/specific-next-page,所有静态资源请求路径会变为/specific-next-page/_next/...,会被高优先级的location规则直接代理到Next.js服务,不会再被WordPress的静态规则、PHP规则拦截,404问题即可解决。
额外说明:如果不想修改Next.js的basePath配置,也可以在
location /specific-next-page段中添加sub_filter规则,将返回内容里的/_next/替换为/specific-next-page/_next/,但这种方式兼容性差,Next.js版本升级后很容易失效,不属于官方推荐方案,优先使用basePath配置实现子路径部署。
内容的提问来源于stack exchange,提问作者adielbm

