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

Node.js缓存静态文件响应至变量:需替代res.sendFile避免重复读盘

缓存res.sendFile完整响应以替代重复硬盘读取

要实现缓存res.sendFile对应的完整响应(而非单纯文件内容),核心是预加载时不仅保存文件内容,还要同步记录sendFile会自动设置的响应头信息(尤其是Content-Type),请求时直接复用这些头和内容即可。下面是基于Express的具体实现方案:

1. 预加载静态文件到缓存

首先定义需要缓存的文件列表,遍历读取每个文件的内容,同时获取对应的MIME类型,将响应头和内容一起存入缓存对象:

const fs = require('fs');
const path = require('path');
const mime = require('mime-types'); // 用于自动获取文件MIME类型
const express = require('express');
const app = express();

// 缓存容器:键为请求路径,值为包含响应头和内容的对象
const staticCache = {};

// 你的10个静态文件路径列表
const targetFiles = [
  '/css/main.css',
  '/js/bundle.js',
  '/img/banner.jpg',
  '/fonts/OpenSans-Regular.ttf',
  // 补充剩余6个文件路径
];

// 预加载函数
function loadStaticCache() {
  targetFiles.forEach(filePath => {
    // 拼接文件的本地绝对路径(假设静态文件存放在项目根目录的public文件夹下)
    const localPath = path.join(__dirname, 'public', filePath);
    
    // 读取文件为Buffer(二进制文件如图片、字体必须用Buffer)
    const fileContent = fs.readFileSync(localPath);
    
    // 获取对应文件的MIME类型, fallback到二进制流类型
    const contentType = mime.lookup(localPath) || 'application/octet-stream';
    
    // 存入缓存:包含响应头和文件内容
    staticCache[filePath] = {
      headers: {
        'Content-Type': contentType,
        'Content-Length': fileContent.length,
        // 可根据需求添加缓存控制头,比如长期缓存静态资源
        'Cache-Control': 'public, max-age=31536000'
      },
      content: fileContent
    };
  });
}

// 服务启动时执行预加载
loadStaticCache();

2. 请求时直接返回缓存的完整响应

在路由中,先检查请求路径是否存在于缓存中,若存在则直接用res.writeHead设置预存的响应头,再用res.end发送内容,完全模拟res.sendFile的响应效果:

// 处理静态文件请求的路由
app.get(['/css/*', '/js/*', '/img/*', '/fonts/*'], (req, res) => {
  const reqPath = req.path;
  const cachedData = staticCache[reqPath];
  
  if (cachedData) {
    // 设置响应头+发送内容
    res.writeHead(200, cachedData.headers);
    res.end(cachedData.content);
  } else {
    // 缓存未命中时的降级处理,比如返回404或走原sendFile逻辑
    res.status(404).send('Static file not found');
  }
});

// 启动服务
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

关键说明

  • 为什么要缓存响应头?res.sendFile的核心作用之一就是根据文件后缀自动匹配正确的Content-Type,比如css文件返回text/css、字体文件返回font/ttf,如果只缓存文件内容,返回时无法自动设置这些头,会导致浏览器无法正确解析资源。
  • 关于mime-types模块:可以自动维护最全的MIME类型映射,避免手动写大量if-else判断文件后缀,安装命令为npm install mime-types。
  • 缓存更新:如果静态文件有修改,需要重启服务重新加载缓存;若需要热更新,可以监听文件变化事件,触发缓存重新加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:20:27