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

如何清除Express.js缓存,提供每秒更新的JSON文件服务?

问题描述

我正在编写一个程序,通过Express.js提供JSON格式的实时信息供另一程序使用,当前用于每秒上报CPU使用率。JSON文件本身更新正常,但Express.js始终缓存首个版本,无法返回最新内容。我已尝试删除require缓存、安装express-reload等方法,但均未解决问题。

现有循环代码(收集并提供数据)

setInterval(() => {
    Monitor.run()

    ServerInstance.serveData(require('../data.json'));
}, 1000);

serveData函数实现

serveData (data) {
        this.app.get('/', (_request, response) => {
            response.setHeader('Content-Type', 'application/json');
            response.json(data);
        })
}

补充尝试(使用fs.readFile)

我尝试使用fs.readFile获取最新数据并传给Express,控制台能输出正确的更新后数据,但Express仍返回程序启动时的首个数据,请问我忽略了什么关键点?

对应的代码:

fs.readFile(__dirname + '/../data.json', 'utf-8', (error, data) => {
    if (error) console.error(error);

    // 此处输出正确信息
    console.log(data);
    // 但Express仍返回初始数据
    ServerInstance.serveData(data);
})

问题根源与解决方案

你的核心问题是重复调用app.get('/')注册路由,但Express只会保留第一个注册的路由处理函数。每次调用serveData时,你都在给根路径添加新的处理函数,但客户端请求时,Express只会执行第一个注册的那个,所以永远返回初始数据。

正确实现方式

不需要每次更新数据就重新注册路由,而是让路由处理函数在每次请求时主动获取最新数据:

方案1:路由触发时实时读取文件

初始化时只注册一次路由,每次请求触发时读取最新的JSON文件内容:

// 只在初始化时注册一次路由
this.app.get('/', (_request, response) => {
    response.setHeader('Content-Type', 'application/json');
    fs.readFile(__dirname + '/../data.json', 'utf-8', (error, data) => {
        if (error) {
            console.error(error);
            return response.status(500).json({ error: '读取数据失败' });
        }
        // 解析JSON字符串并返回
        response.json(JSON.parse(data));
    });
});

方案2:维护内存实时数据,路由直接返回

如果不想每次请求都读文件,可以在定时任务里更新内存变量,路由直接返回这个变量(性能更优):

// 初始化内存变量存储实时数据
let realtimeData = {};

// 定时任务更新内存数据
setInterval(() => {
    Monitor.run();
    fs.readFile(__dirname + '/../data.json', 'utf-8', (error, data) => {
        if (!error) {
            realtimeData = JSON.parse(data);
        }
    });
}, 1000);

// 只注册一次路由
this.app.get('/', (_request, response) => {
    response.setHeader('Content-Type', 'application/json');
    response.json(realtimeData);
});

为什么之前的方法无效?

  • 使用require('../data.json')时,Node.js会缓存模块内容,即使文件更新,require也不会自动重新读取,手动清缓存不是最优解。
  • 多次调用app.get('/')会添加多个路由处理函数,但Express匹配路由时会按注册顺序执行第一个匹配的函数,后续添加的处理函数永远不会被触发,所以不管传入什么新data,返回的都是第一个注册函数里的初始数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:31:25