如何在Node.js中读取RAR文件并动态生成图片画廊?
Node.js实现无磁盘存储的RAR图片画廊
我需要实现一个无需将文件保存到磁盘的动态HTML图片画廊,能够从单个RAR文件或分卷RAR文件(如rar、r01、r02等)中提取图片数据生成画廊。之前用Flask+Python实现过该功能,现在需要Node.js方案,要求支持Blob或Buffer,且能处理大文件。
当前实现代码
服务端(Express)代码
import express from 'express'; import path from 'path'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import { createExtractorFromFile } from 'node-unrar-js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const app = express(); const PORT = 3000; // 配置静态文件目录,用于托管HTML和JS文件 app.use(express.static(path.join(__dirname, 'public'))); // 本地RAR文件路径 const rarFilePath = path.join(__dirname, 'example_rar_5.rar'); // 获取图片列表的接口 app.get('/images', async (req, res) => { try { // 从文件创建RAR提取器 const extractor = await createExtractorFromFile({ filepath: rarFilePath }); const extracted = extractor.extract(); // 将生成器转换为数组 const files = [...extracted.files]; console.log('提取到的文件:', files); // 打印文件结构用于调试 // 筛选图片文件(支持png/jpg/jpeg/gif) const imageFiles = files.filter(file => /\.(png|jpg|jpeg|gif)$/.test(file.fileHeader.name)); // 提取图片文件名列表 const imageFilenames = imageFiles.map(file => file.fileHeader.name); res.json(imageFilenames); } catch (error) { console.error('获取图片列表出错:', error); res.status(500).send('处理RAR文件失败'); } }); // 按文件名提供图片Blob的接口 app.get('/images/:filename', async (req, res) => { const filename = req.params.filename; try { const extractor = await createExtractorFromFile({ filepath: rarFilePath }); const extracted = extractor.extract(); const files = [...extracted.files]; // 查找对应文件名的文件 const file = files.find(file => file.fileHeader.name === filename); if (file) { const fileBuffer = file.fileData; // 获取文件内容Buffer // 设置正确的Content-Type res.set('Content-Type', filename.endsWith('.png') ? 'image/png' : 'image/jpeg'); res.send(fileBuffer); // 发送图片Buffer } else { res.status(404).send('文件不存在'); } } catch (error) { console.error('提取图片出错:', error); res.status(500).send('处理RAR文件失败'); } }); // 启动服务器 app.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`); });
前端(index.html)代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>RAR图片查看器</title> </head> <body> <h1>RAR中的图片</h1> <div id="image-container"></div> <script> const imageContainer = document.getElementById('image-container'); // 请求获取图片列表 fetch('/images') .then(response => response.json()) .then(imageFilenames => { imageFilenames.forEach(filename => { // 请求单个图片文件 fetch(`/images/${filename}`) .then(response => response.blob()) .then(blob => { const img = document.createElement('img'); img.src = URL.createObjectURL(blob); // 为Blob创建临时URL img.alt = filename; img.style.width = '200px'; img.style.margin = '10px'; imageContainer.appendChild(img); }) .catch(error => { console.error('加载图片出错:', error); }); }); }) .catch(error => { console.error('加载图片列表出错:', error); }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者kasten
相关产品推荐
相关产品推荐

