You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 12升级至14后Standalone模式Express代理404问题

Next.js 14 Standalone构建升级后404问题修复方案

问题背景

修改Standalone输出文件.next/standalone/server.js添加Express代理后,将Next.js从12.3.0升级到14.0.4,执行node server.js启动服务器并访问localhost:3000出现404错误。

环境信息

  • next 12.0.3 → 14.0.4
  • nodeJs 18.17.1
  • yarn 1.22.21

核心原因

Next.js 14的Standalone构建输出结构、内部初始化逻辑均有调整,直接修改生成的server.js会导致Next无法正确定位页面资源,正确做法是自定义独立的Express服务器文件,而非修改自动生成的文件。

具体修改步骤

1. 项目根目录新建自定义server.js

不再修改.next/standalone/server.js,在项目根目录创建自己的服务器文件:

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const express = require('express');
const helmet = require('helmet');
const { createProxyMiddleware } = require('http-proxy-middleware');
const https = require('https');
const next = require('next');

// HTTPS证书配置
const options = {
  key: fs.readFileSync('./ca/server.key'),
  cert: fs.readFileSync('./ca/server.crt'),
};

const dev = false;
const app = next({ dev, dir: path.join(__dirname) });
const handle = app.getRequestHandler();

const currentPort = 3000;

// 优雅处理进程终止信号
if (!process.env.NEXT_MANUAL_SIG_HANDLE) {
  process.on('SIGTERM', () => process.exit(0));
  process.on('SIGINT', () => process.exit(0));
}

app.prepare().then(() => {
  const server = express();

  // 自定义请求中间件
  server.use((req, res, next) => {
    res.locals.cspNonce = crypto.randomBytes(16).toString('hex');
    res.setHeader('Permissions-Policy', 'geolocation=(self)');
    next();
  });

  // Helmet安全配置
  server.use(
    helmet({
      contentSecurityPolicy: {
        directives: {
          'script-src': ["'self'", "'unsafe-eval'", "'unsafe-inline'"],
          'style-src': ["'self'", "'unsafe-inline'"],
          'img-src': ["'self'", 'data:'],
          'object-src': ["'none'"],
          'form-action': ["'none'"],
          'font-src': ["'self'"],
        },
      },
      strictTransportSecurity: {
        maxAge: 31536000,
        preload: true,
      },
    }),
  );

  // 静态资源映射:Next.js 14需明确处理_next/static路径
  server.use('/_next/static', express.static(path.join(__dirname, '.next', 'static')));
  server.use(express.static('public'));

  // API代理配置
  server.use(
    '/api/proxy',
    createProxyMiddleware({
      target: 'http://localhost:3001',
      pathRewrite: {
        '^/api/proxy': '/api/proxy',
      },
      ws: true,
      onProxyReqWs: (proxyReq, req, res) => {
        let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
        proxyReq.setHeader('x-forwarded-for', ip);
      },
    }),
  );

  // 所有请求交由Next处理
  server.all('*', (req, res) => {
    return handle(req, res);
  });

  // 启动HTTPS服务器
  https.createServer(options, server).listen(currentPort, (err) => {
    if (err) {
      console.error('Failed to start server', err);
      process.exit(1);
    }
    console.log('Listening on port', currentPort);
  });
});

2. 调整next.config.js(保持核心配置)

无需大幅修改,确保output: 'standalone'配置存在即可:

const nextConfig = {
  output: 'standalone',
  reactStrictMode: false,
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://localhost:3001/api/:path*',
      },
    ];
  },
  webpack(config) {
    const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg'));
    config.module.rules.push(
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: { not: /svgr/ },
      },
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        resourceQuery: /svgr/,
        use: ['@svgr/webpack'],
      },
    );
    return config;
  },
};

module.exports = nextConfig;

3. 修改构建与部署流程

  • 执行yarn build生成.next/standalone目录
  • 部署时需包含以下文件/目录:
    • 根目录的自定义server.js
    • .next/standalone目录
    • .next/static目录
    • public目录
    • ca证书目录(若使用HTTPS)
  • 服务器启动命令:node server.js

Next.js 14 Standalone关键变化

  • 官方不再推荐直接修改自动生成的server.js,建议通过自定义独立服务器扩展功能
  • 静态资源路径需明确映射/_next/static,否则会导致页面资源加载404
  • 初始化逻辑简化,使用next()方法替代直接实例化NextServer,避免内部API变更引发兼容问题

内容的提问来源于stack exchange,提问作者LEECHANGHUN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:44:56