基于Node.js的ePub阅读器后端:MongoDB存储及文件传输问题咨询
Node.js ePub阅读器后端相关问题解答
1. ePub文件能否存储至MongoDB?
可以。MongoDB支持两种文件存储方式:
- 对于小于16MB的ePub文件,可直接将文件转为Buffer,存储在普通MongoDB文档的
Buffer类型字段中。 - 对于大于16MB的ePub文件,建议使用MongoDB的GridFS规范,它会将大文件分割为多个chunk存储,适配MongoDB单文档16MB的限制,同时支持流式读写。
如果文件数量多、体积大,也可以考虑结合对象存储服务,仅在MongoDB中存储文件的元数据和访问地址,这种方案的性能与扩展性更优。
2. 控制台读取ePub文件并传递至前端的实现示例
以下是基于Express框架的完整实现,包含后端读取本地文件、提供接口,以及前端接收处理的代码:
后端代码(读取本地ePub并提供接口)
const express = require('express'); const fs = require('fs').promises; const path = require('path'); const app = express(); // 跨域配置(按需添加) app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET'); next(); }); // 接口:返回示例ePub文件 app.get('/api/epub/sample', async (req, res) => { try { // 替换为你的ePub文件本地路径 const epubFilePath = path.resolve(__dirname, './sample.epub'); const epubBuffer = await fs.readFile(epubFilePath); // 设置响应头,指定文件MIME类型 res.set('Content-Type', 'application/epub+zip'); // 若需要让浏览器直接下载,可添加以下头 // res.set('Content-Disposition', 'attachment; filename="sample.epub"'); // 将文件Buffer发送给前端 res.send(epubBuffer); } catch (error) { console.error('读取ePub文件失败:', error); res.status(500).json({ message: '获取ePub文件失败' }); } }); const PORT = 3000; app.listen(PORT, () => { console.log(`后端服务运行在 http://localhost:${PORT}`); });
前端代码(接收并处理ePub文件)
// 使用Fetch API请求后端接口 async function getSampleEpub() { try { const response = await fetch('http://localhost:3000/api/epub/sample'); if (!response.ok) throw new Error('请求异常'); // 将响应转为Blob对象 const epubBlob = await response.blob(); // 方案1:创建下载链接让用户保存文件 const downloadUrl = URL.createObjectURL(epubBlob); const downloadLink = document.createElement('a'); downloadLink.href = downloadUrl; downloadLink.download = 'sample.epub'; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); URL.revokeObjectURL(downloadUrl); // 方案2:传递给ePub解析库(如epub.js)直接在线解析 // const reader = new Epub(epubBlob); // await reader.ready; // 后续进行阅读器渲染逻辑 } catch (error) { console.error('获取ePub文件失败:', error); } } // 调用函数获取文件 getSampleEpub();
补充:将ePub存储至MongoDB的示例(GridFS)
如果需要将上传的ePub文件存储到MongoDB,这里提供基于GridFS的实现示例:
const mongoose = require('mongoose'); const Grid = require('gridfs-stream'); const fs = require('fs'); // 连接MongoDB数据库 mongoose.connect('mongodb://localhost:27017/epub_reader_db', { useNewUrlParser: true, useUnifiedTopology: true }); const db = mongoose.connection; let gfs; db.once('open', () => { // 初始化GridFS gfs = Grid(db.db, mongoose.mongo); gfs.collection('epubs'); // 指定存储文件的集合名 }); // 示例:上传本地ePub到GridFS function uploadEpubToMongo() { const readStream = fs.createReadStream('./sample.epub'); const writeStream = gfs.createWriteStream({ filename: 'sample.epub', contentType: 'application/epub+zip', metadata: { author: 'Sample Author' } // 可附加自定义元数据 }); readStream.pipe(writeStream); writeStream.on('close', (file) => { console.log(`文件已存储到MongoDB,文件ID: ${file._id}`); }); } // 调用上传函数 uploadEpubToMongo(); // 从GridFS读取文件并返回给前端的接口 app.get('/api/epub/:fileId', (req, res) => { gfs.files.findOne({ _id: mongoose.Types.ObjectId(req.params.fileId) }, (err, file) => { if (err || !file) { return res.status(404).json({ message: '文件不存在' }); } // 创建读取流并返回给前端 const readStream = gfs.createReadStream(file.filename); res.set('Content-Type', file.contentType); readStream.pipe(res); }); });
内容的提问来源于stack exchange,提问作者Hyunsu Kim
相关产品推荐
相关产品推荐

