Next.js 部署后刷新页面 404

FreeGuideOnline 最新 2026-07-04

Next.js 部署后刷新页面 404:原因与终极解决方案

你是否遇到过这样的场景:在本地开发时 Next.js 应用路由一切正常,但部署到服务器后,手动刷新页面或直接访问某个子路由时,却返回了冰冷的 404 错误?这篇教程将带你从根源上理解问题,并提供针对不同部署环境的一站式解决方案,即使你是后端基础较弱的初学者也能轻松上手。


一、问题复现:刷新为什么会 404?

假设你的 Next.js 应用有两个页面:

  • /(首页)
  • /about(关于页)

本地使用 next dev 启动时,访问 http://localhost:3000/about 不会出错。
但部署到生产环境后,在浏览器中 直接输入域名/about在/about页面按F5刷新,就会出现 404。

究其原因,这与 Next.js 的路由机制 以及 部署环境如何处理请求 密切相关。


二、核心原因:客户端路由与服务器端文件查找的冲突

Next.js 是一个混合框架,支持两种渲染模式:

  1. 静态生成(Static Generation):在构建时即生成 HTML 文件。
  2. 服务端渲染(SSR)或增量静态再生成(ISR):请求到来时动态生成页面。

当你使用 <Link href="/about"> 进行导航时,Next.js 会拦截点击事件,通过浏览器的 History API 在前端进行路由切换,根本不会向服务器发起完整的页面请求。页面内容由 JavaScript 动态替换,所以一切正常。

但当你刷新页面直接访问 /about 时,浏览器会向服务器发送一个真实的 HTTP 请求(例如 GET /about)。此时:

  • 如果 /about 页面是纯静态生成(next build && next export 或单独生成):服务器上必须存在 about.html 这个物理文件。Nginx、Apache 这类传统静态服务器是根据 URL 路径去文件系统查找对应文件的,如果找不到,就会返回 404。
  • 如果使用 Node.js 服务器或 Serverless 平台(如 Vercel):服务器默认能正确将所有请求指向 next start 处理,它们会自动将 /about 映射到 Next.js 的 pages/about.js,然后决定渲染 SSR 还是返回静态文件。因此一般不会有问题。

核心矛盾
Next.js 是单页应用(SPA)风格的框架,但它的“页面”并不完全是实际存在的静态文件。传统静态服务器的“文件名匹配”逻辑无法理解前端路由结构。


三、不同部署方案的“对症下药”

下面根据你实际选择的部署方式,给出最直接的修复方案。请对号入座。

3.1 使用 Vercel / Netlify(推荐零配置方案)

如果你将项目部署到 Vercel(Next.js 官方平台),默认自带完美的路由处理,无需任何额外配置,所有子路由都能正常刷新。
这就是为什么很多教程说“部署到 Vercel 就解决了”——因为它内置了对 next build 的完整支持。

Netlify 也提供了类似的 Next.js 适配插件。
建议在项目根目录创建 netlify.toml,使用 Next.js 的必要构建插件:

[build]
  command = "npm run build"
  publish = "out"  # 如果你使用 next export,填out;若使用serverless插件则按插件说明

[[plugins]]
  package = "@netlify/plugin-nextjs"

部署后刷新即可正常运行。


3.2 使用静态导出(next export)部署到任意静态服务器

如果你必须使用 next export 生成纯静态 HTML 文件(类似于 Gatsby 的构建方式),那么:

  • 导出命令:npx next build && npx next export
  • 输出目录通常是 out/

此时每一个页面都会被生成为对应的 HTML 文件,例如 about.html
但你直接访问 /about 时,服务器需要知道 about 对应 about.html。因此必须配置 URL 重写规则,让服务器自动补全 .html 后缀或将所有未知路径回退到 index.html(后者更适合 SPA 模式,但 Next.js 静态导出通常保留真实路径)。

Nginx 示例(补全 .html 后缀):

server {
    listen 80;
    server_name example.com;
    root /var/www/out;

    location / {
        # 尝试直接访问URI,不存在则尝试加上.html后缀
        try_files $uri $uri.html $uri/ =404;
    }
}

Apache 示例(.htaccess 文件):

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^(.+?)/?$ $1.html [L]

配置后,访问 /about 会返回 about.html 的内容。

注意:如果你的页面中有动态路由(例如 [id].js),静态导出会将数据预渲染到对应的 HTML 中,但刷新时路径结构必须符合导出规则。


3.3 使用 Nginx 反向代理 Node.js 服务器(next start)

很多自建服务器用户喜欢用 Nginx 做反向代理,将请求转发给本地运行的 next start。这种情况下,Nginx 必须将所有无法匹配的请求(或所有请求)都交给 Node.js 处理,否则仍会 404。

标准配置如下:

server {
    listen 80;
    server_name your-domain.com;

    location /_next/static {
        alias /path/to/your/.next/static;
        expires 365d;
    }

    location / {
        proxy_pass http://localhost:3000; # next start 运行的端口
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

关键的 location / 块会将除静态资源外的流量全数转发给 Next.js。这样刷新任何页面都不会 404。


3.4 使用 Docker 或直接运行 next start(无 Nginx)

如果你的应用直接通过 npm run start(即 next start)对外服务,并且没有前置反向代理,则刷新页面通常不会 404。因为 Next.js 的生产服务器本身就能正确处理所有路由。
但请确保:构建和启动命令正确

  • 构建:npx next build(生成 .next 文件夹)
  • 启动:npx next start(读取 .next 并启动服务器)

只要你没有删除 .next 目录,直接访问子路由就无忧。


3.5 使用云服务(阿里云 OSS / AWS S3)托管静态导出文件

在对象存储类服务中托管静态网站,需要配置错误文档(索引文档)处理重定向规则

AWS S3 为例:

  • 开启静态网站托管。
  • 索引文档设置为 index.html
  • 错误文档也设置为 index.html(适用于 SPA 回退,但会将全部 404 回退到首页,可能影响 SEO)。
  • 更好的方式是:使用 CloudFront 添加 自定义错误响应,当 HTTP 404 时,响应路径改为 /index.html,状态码改为 200。

阿里云 OSS
在控制台设置 默认首页index.html默认 404 页 同样指向 index.html(SPA 方案),或者更精细地设置 CDN 回源规则,对不同路径进行重写。

⚠️ 注意:如果大量使用回退至 index.html,虽然解决了刷新 404,但会丢失原始 URL 信息,不利于 SEO,推荐仅在无奈情况下使用。


四、进阶:使用 Hash 路由(不推荐,但可行)

如果你完全无法控制服务器配置(例如一些老旧的主机),并且使用的是纯静态导出,可以考虑将 Next.js 的链接改为 Hash 路由
但这需要舍弃 Next.js 原生基于路径的路由,引入第三方库(如 react-router 的 HashRouter),与 Next.js 的文件系统路由体系冲突,迁移成本极高, 不推荐作为常规方案。仅在极其受限的环境中考虑。

一个更简单的“折中”是:所有页面作为单页面应用(SPA)模式,通过一个 index.html 承载,配合 next/router,但同样需要改动较大,且失去 SEO 优势。


五、总结:你的 404 解决路线图

你的部署方式 最快解决方案
Vercel / Netlify 无需任何操作,默认支持。
静态导出 + Nginx/Apache 配置 try_files.htaccess 重写。
Nginx 反向代理 next start / 下的请求全部 proxy_pass 到 Node。
直接运行 next start 确保正确执行 build 和 start。
对象存储(OSS/S3) 设置错误文档回退至 index.html 或重写。

根本原则:部署环境必须理解 “每个路由都可以回退给 Next.js 处理”,无论是通过服务器重定向还是反向代理。一旦你理解了这个本质,所有平台的配置都变得异曲同工。

现在,对照你的部署方案,操练起来吧!只需几分钟的配置,即可让刷新 404 永远消失。