xvno / blog

个人博客, 不定期发布技术笔记和个人随笔.
0 stars 0 forks source link

PL: node.js: egg.js #163

Open xvno opened 2 years ago

xvno commented 2 years ago

Refs

xvno commented 2 years ago

1. 文件下载

Refs

1.1 方案

1.1.1 最简单实现方式, 省略了错误处理。

// controller/Foo.ts
async download() {
  const filePath = '/path/to/file';
  this.ctx.attachment(filePath);
  this.ctx.set('Content-Type', 'application/octet-stream');
  this.ctx.body = fs.createReadStream(filePath);
}

1.1.2 支持进度条和剩余时间(加入 Content-Length)

仅需这样实现,即可实现下载,但这样实现的下载会发现没有下载进度条,也不知道还有多久下载完。原因 HTTP 返回头里没有 Content-Length。

// controller/Foo.ts
async download() {
  const filePath = '/path/to/file';
  const fileSize = (await promisify(stat)(filePath)).size.toString();
  this.ctx.attachment(filePath);
  this.ctx.set('Content-Length', fileSize);
  this.ctx.set('Content-Type', 'application/octet-stream');
  this.ctx.body = createReadStream(filePath);
}

1.1.3 支持断点续传(加入 Range 和 Content-Range)

在服务端我们需要处理客户端请求头中的 Range 字段,同时再返回 Content-Range。

利用Koa生态的koa-range来实现: koa-range

先创建一个中间件:

// app/middleware/range.ts
import * as KoaRange from 'koa-range';
export default function RangeMiddleware() {
  return KoaRange;
}

然后在配置中启用它:

// config/config.default.ts
import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg';

export default (appInfo: EggAppInfo) => {
  const config = {} as PowerPartial<EggAppConfig>;
  config.middleware = ['range'];
  return config;
};

使用 wget 测试一下,加入 -c 就可以了:

wget -c http://domain/path/to/file.tar.gz

file.tar.gz          27%[++========>                             ]   1.28G  1.52MB/s    in 12m 39s
xvno commented 2 years ago

2. 文件上传