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

Router.push()跳转后Node.js fs.readdirSync未触发服务端代码的解决方法

解决方案:触发根页面服务端代码执行的跳转方式

你遇到的核心问题是 Next.js的Router.push()属于客户端SPA跳转,不会向服务器发起新请求,所以根页面里依赖服务端环境的fs.readdirSync()代码完全不会运行——毕竟SPA跳转只是在浏览器端切换页面内容,根本没给服务器触发代码的机会。

下面给你两种针对性的解决方案,按需选择:

方案1:直接触发完整浏览器跳转(最简单直接)

用原生的window.location.href替代Router.push(),这种方式会让浏览器像手动输入网址一样发起完整的GET请求,服务器必然会处理根路径的请求,你的服务端文件读取代码也就会执行了。

修改你的跳转逻辑:

goTo = (item) => {
  console.log('goTo: ', item);
  window.location.href = '/';
}

唯一的小缺点是会有页面刷新的白屏,但胜在逻辑简单,完全满足你“必须执行服务端代码”的核心需求。

方案2:保留SPA体验+服务端数据获取(进阶优化)

如果想兼顾SPA跳转的流畅性,同时获取服务端的最新文件列表,可以结合Next.js的服务端数据获取能力和API路由来实现:

步骤1:将服务端逻辑迁移到getServerSideProps

在根页面pages/wiki/index.js中,把读取文件列表的逻辑放到getServerSideProps里——这是Next.js专门用于服务端数据获取的方法,会在每次请求(包括客户端跳转后的首次渲染)时执行:

export async function getServerSideProps(context) {
  const { query } = context;
  const versions = articles.getVersions(`articles/${query.article}/`);
  return {
    props: { versions } // 把数据传递给页面组件
  }
}

function WikiPage({ versions }) {
  // 用获取到的versions渲染页面内容
  return (
    <div>
      {/* 你的文件列表渲染逻辑 */}
    </div>
  )
}

export default WikiPage;

步骤2:创建API路由用于客户端补取数据

如果客户端跳转后发现数据缺失(比如某些极端情况),可以通过API路由从服务端重新获取:
创建pages/api/get-versions.js:

import articles from '../../path/to/Articles'; // 替换成你的Articles模块路径

export default function handler(req, res) {
  const { article } = req.query;
  try {
    const versions = articles.getVersions(`articles/${article}/`);
    res.status(200).json({ versions });
  } catch (err) {
    res.status(500).json({ error: 'Failed to fetch versions' });
  }
}

步骤3:在页面组件中处理数据补取

在根页面组件中,用useEffect检查数据是否存在,如果不存在就调用API获取:

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';

function WikiPage({ versions: initialVersions }) {
  const [versions, setVersions] = useState(initialVersions);
  const { article } = useRouter().query; // 用useRouter获取query参数

  useEffect(() => {
    // 如果初始数据为空,从API拉取
    if (!versions && article) {
      fetch(`/api/get-versions?article=${encodeURIComponent(article)}`)
        .then(res => res.json())
        .then(data => setVersions(data.versions));
    }
  }, [versions, article]);

  // 渲染逻辑
  return (
    <div>
      {versions ? (
        /* 渲染文件列表 */
      ) : (
        <p>加载中...</p>
      )}
    </div>
  )
}

export default WikiPage;

这种方式既保留了SPA跳转的流畅性,又能确保你获取到服务端的最新文件列表。

内容的提问来源于stack exchange,提问作者Vinícius de Araújo Portela

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:53:40