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

Next.js使用Express自定义服务器时getInitialProps重复调用问题

问题原因
  • 路由注册顺序错误:Express 服务的 server.listen() 启动逻辑写在了通配符路由 server.get('*') 之前,服务启动时路由尚未完成挂载,请求会先触发 Next.js 内置路由处理,再触发自定义路由逻辑,产生额外调用。
  • 未正确关闭 Next.js 内置文件路由:你提到已禁用 pages 文件夹路由,但初始化 Next 实例时未添加 useFileSystemPublicRoutes: false 配置,Next.js 默认仍会扫描 pages 目录匹配路由,和自定义路由产生冲突,导致重复执行 getInitialProps。
  • React.StrictMode 开发环境特性:开启 StrictMode 时,开发环境下 React 会重复调用部分生命周期方法(包括客户端侧的 getInitialProps)用于检测副作用,你观察到的两次调用分别是服务端渲染触发、StrictMode 下客户端重复执行的结果;关闭 StrictMode 后因为前述两个路由冲突问题,多触发了一次路由匹配调用,因此变成三次。
解决方案
  1. 修正路由注册顺序,将通配符路由逻辑移到 server.listen() 之前,确保服务启动前所有路由已完成挂载。
  2. 初始化 Next.js 实例时添加 useFileSystemPublicRoutes: false 配置,彻底关闭内置文件系统路由,避免路由冲突。
  3. 开发环境下的 StrictMode 重复调用属于官方预设调试行为,生产环境构建后会自动消失,无需额外处理。

修正后的 server.js 参考代码

require('dotenv').config();
const express = require('express');
const next = require('next');
const mongoose = require('mongoose');
    
const dev = process.env.NODE_ENV !== 'production';
// 新增配置关闭内置文件路由
const app = next({ dev, useFileSystemPublicRoutes: false });

mongoose.connect(process.env.DB_URI)
.then(()=>{
  console.log('>Succesfully connected to the database');
  
  app.prepare()
  .then(() => {
    const server = express();

    // 先注册路由
    server.get('*', (req, res)=>{
      app.render(req, res, '/index', {something:true});
    })

    // 最后启动服务
    server.listen(3000, (req, res) =>{
      console.log('>Listening on port 3000');
    });
    
  })
  .catch((ex) => {
    console.error(ex.stack);
    process.exit(1);
  })

})
.catch(e=>{
  console.log('<!>Error connecting to database: \n' + e);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:15:02