Koa2 是一个基于 Node.js 的轻量级框架,它提供了一套简单、强大的 API,让开发者能够轻松构建 Web 应用程序。在 Web 应用程序的开发中,通常需要实现上传和下载的功能,本文将介绍如何基于 Koa2 实现一个简单的上传服务和下载服务。
准备工作
在开始编写代码前,我们需要安装几个依赖包:
- Koa2
- Koa-body
- Koa-router
- Multer
- Mime-types
我们可以使用 npm 进行安装:
npm install koa koa-body koa-router multer mime-types --save
实现上传服务
初始化 Koa2 应用程序
我们可以通过以下代码初始化一个 Koa2 应用程序:
const Koa = require('koa'); const app = new Koa();
配置 Koa-body 和 Multer
Koa-body 是一个中间件,它用于解析 HTTP 请求的 body。Multer 则是一个 Node.js 中间件,用于处理文件上传。我们需要把它们两个都配置到应用程序中:
const KoaBody = require('koa-body'); const Multer = require('multer'); // 配置 Koa-body app.use(KoaBody()); // 配置 Multer const storage = Multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads/'); // 文件存储的目录 }, filename: function (req, file, cb) { cb(null, `${file.originalname}`); // 文件名 } }); const upload = Multer({ storage: storage });
实现上传接口
下面我们来实现一个上传接口:
const KoaRouter = require('koa-router'); const router = new KoaRouter(); router.post('/upload', upload.single('file'), (ctx, next) => { if (ctx.req.file) { ctx.status = 200; ctx.body = { success: true, message: '文件上传成功!', data: { url: `http://localhost:3000/uploads/${ctx.req.file.originalname}`, } }; } else { ctx.status = 500; ctx.body = { success: false, message: '文件上传失败!', }; } }); app.use(router.routes());
如上代码所示,我们首先通过 KoaRouter 配置一个上传路由,上传的入口 URL 是 /upload
,在上传时使用了 upload.single('file') 中间件,它表示只允许上传一个名为 'file' 的文件。如果上传成功,则返回一个 JSON 响应,包含了成功标志、消息和所上传文件的 URL,否则返回错误消息。
实现下载服务
实现一个下载接口
下面我们来编写一个下载接口,用户可以通过该接口下载上传的文件:
const fs = require('fs'); const mime = require('mime-types'); router.get('/download/:filename', async (ctx, next) => { const filename = ctx.params.filename; const path = `./uploads/${filename}`; const fStats = await fs.promises.stat(path); if (fStats.isFile()) { ctx.set('Content-type', mime.lookup(path)); ctx.body = fs.createReadStream(path); } else if (fStats.isDirectory()) { ctx.status = 400; ctx.body = { success: false, message: '无法下载一个目录!', }; } });
如上代码所示,该接口允许用户通过 /download/:filename
进行下载,:filename 是动态路由参数,表示要下载的文件名称。该接口首先通过 Node.js 的 fs 模块检查文件存在性,并检查用户请求下载的是否是一个目录(目录无法下载)。如果请求下载的是个文件,则设置 Content-type 响应头,并将文件内容通过 fs.createReadStream 输出到响应主体中。
总结
到此为止,我们已经介绍了基于 Koa2 实现一个简单的上传和下载服务的实现过程,其中使用了 Koa-body、Koa-router、Multer 和 Mime-types 等多个 Node.js 模块。当然,这个示例还可以进行更加复杂的处理,例如文件格式检查、文件上传进度反馈等等,希望这篇文章能够给读者提供启示,并为日后的项目开发提供帮助。最后,本文的示例代码如下:
const Koa = require('koa'); const app = new Koa(); const KoaBody = require('koa-body'); const Multer = require('multer'); const fs = require('fs'); const mime = require('mime-types'); const KoaRouter = require('koa-router'); app.use(KoaBody()); const storage = Multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads/'); // 文件存储的目录 }, filename: function (req, file, cb) { cb(null, `${file.originalname}`); // 文件名 } }); const upload = Multer({ storage: storage }); const router = new KoaRouter(); router.post('/upload', upload.single('file'), (ctx, next) => { if (ctx.req.file) { ctx.status = 200; ctx.body = { success: true, message: '文件上传成功!', data: { url: `http://localhost:3000/uploads/${ctx.req.file.originalname}`, } }; } else { ctx.status = 500; ctx.body = { success: false, message: '文件上传失败!', }; } }); router.get('/download/:filename', async (ctx, next) => { const filename = ctx.params.filename; const path = `./uploads/${filename}`; const fStats = await fs.promises.stat(path); if (fStats.isFile()) { ctx.set('Content-type', mime.lookup(path)); ctx.body = fs.createReadStream(path); } else if (fStats.isDirectory()) { ctx.status = 400; ctx.body = { success: false, message: '无法下载一个目录!', }; } }); app.use(router.routes()); app.listen(3000, () => { console.log('文件上传下载服务已启动!'); });
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6591094deb4cecbf2d640336