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
相关产品推荐
相关产品推荐

