乐闻世界logo
搜索文章和话题

How to achieves file download with koa?

9 个月前提问
6 个月前修改
浏览次数127

5个答案

1
2
3
4
5

在 Koa 中实现文件下载功能通常涉及以下几个步骤:

  1. 处理请求:首先,你需要定义一个路由和对应的处理函数来处理下载请求。
  2. 文件定位:处理函数中需要定位到要下载的文件在服务器上的路径。
  3. 设置响应头:为了通知浏览器这是一个文件下载响应,需要设置适当的 Content-DispositionContent-Type 响应头。
  4. 发送文件:最后,使用 Koa 的响应对象来发送文件内容回客户端。

以下是一个简单的例子,演示了如何在 Koa 应用程序中实现文件下载功能:

js
const Koa = require('koa'); const send = require('koa-send'); const path = require('path'); const app = new Koa(); // 定义一个路由用于处理下载请求 app.use(async (ctx) => { // 假设我们要下载的文件名是固定的 const fileName = 'example.txt'; // 设置文件的完整路径 const filePath = path.join(__dirname, 'public', fileName); // 设置响应头 ctx.set('Content-Disposition', `attachment; filename=${fileName}`); ctx.set('Content-Type', 'application/octet-stream'); // 发送文件内容作为响应 await send(ctx, filePath, { root: __dirname }); }); app.listen(3000, () => { console.log('Server running on http://localhost:3000'); });

在这个例子中,当客户端向服务器发送请求时,Koa 应用程序会通过 koa-send 模块来发送位于 public 目录下的 example.txt 文件。Content-Disposition 响应头被设置为 attachment,以及文件的名称,这样浏览器就知道它应该提示用户保存文件而不是直接在浏览器中显示文件的内容。Content-Type 被设置为 application/octet-stream,这是一个通用的二进制文件类型,告诉浏览器这是一个二进制文件。

请注意,这个例子中的文件名是硬编码的,但在实践中,你可能需要根据请求动态地确定文件名和路径。此外,你还可能需要处理诸如文件不存在、权限不足等潜在错误情况。

2024年6月29日 12:07 回复

For anyone else who sees this in the future, it's worth mentioning that there is a built in attachment method on the response object that you can use to set the Content-Disposition to attachment with a specified filename. So you can do this:

shell
this.attachment('hello.txt')

And it would be the same thing as the following:

shell
this.set('Content-disposition', 'attachment; filename=hello.txt')

For Koa 2:

shell
ctx.attachment('hello.txt')
2024年6月29日 12:07 回复

You should be able to simple set this.body to the file stream

shell
this.body = fs.createReadStream(__dirname + '/test.zip');

then set the response headers as appropriate.

shell
this.set('Content-disposition', 'attachment; filename=' + filename); this.set('Content-type', mimetype);
2024年6月29日 12:07 回复

Browser default behaviour is to display the file, not to download it. To enforce download you need to do this:

shell
this.header("Content-Type", "application/force-download") this.header('Content-disposition', 'attachment; filename=' + filename);
2024年6月29日 12:07 回复

Bit of a different file download example with error checking, using Node with Koa 2. I am not sure if it is necessary to destroy the stream afterwards as described here https://github.com/jshttp/content-disposition#options

shell
router.get('/downloads/:version/:file', async function(ctx) { const fileName = `${__dirname}/downloads/${ctx.params.version}/${ctx.params.file}`; try { if (fs.existsSync(fileName)) { ctx.body = fs.createReadStream(fileName); ctx.attachment(fileName); } else { ctx.throw(400, "Requested file not found on server"); } } catch(error) { ctx.throw(500, error); } });

In browser sample: https://myserver.com/downloads/1.0.0/CoolAppFile.zip

2024年6月29日 12:07 回复

你的答案