koa2基于stream(流)进行文件上传和下载

阅读目录

一:上传文件(包括单个文件或多个文件上传)

在之前一篇文章,我们了解到nodejs中的流的概念,也了解到了使用流的优点,具体看我之前那一篇文章介绍的。
现在我们想使用流做一些事情,来实践下它的应用场景及用法。今天我给大家分享的是koa2基于流的方式实现文件上传和下载功能。

首先要实现文件上传或下载肯定是需要使用post请求,以前我们使用 koa-bodyparser这个插件来解析post请求的。但是今天给大家介绍另一个插件 koa-body, 
该插件即可以解析post请求,又支持文件上传功能,具体可以看这篇文章介绍(http://www.ptbird.cn/koa-body.html), 或看官网github(https://github.com/dlau/koa-body).

其次就是koa-body的版本问题,如果旧版本的koa-body通过ctx.request.body.files获取上传的文件。而新版本是通过ctx.request.files获取上传的文件的。否则的话,你会一直报错:ctx.request.files.file ---------->终端提示undefined问题. 如下图所示:

我这边的koa-body 是4版本以上的("koa-body": "^4.1.0",), 因此使用 ctx.request.files.file; 来获取文件了。

那么上传文件也有两种方式,第一种方式是使用form表单提交数据,第二种是使用ajax方式提交。那么二种方式的区别我想大家也应该了解,无非就是页面刷不刷新的问题了。下面我会使用这两种方式来上传文件演示下。

1. 上传单个文件

首先先来介绍下我项目的目录结构如下:

|----项目demo
|  |--- .babelrc       # 解决es6语法问题
|  |--- node_modules   # 所有依赖的包
|  |--- static
|  | |--- upload.html  # 上传html页面
|  | |--- load.html    # 下载html页面
|  | |--- upload       # 上传图片或文件都放在这个文件夹里面
|  |--- app.js         # 编写node相关的入口文件,比如上传,下载请求
|  |--- package.json   # 依赖的包文件

如上就是我目前项目的基本架构。如上我会把所有上传的文件或图片会放到 /static/upload 文件夹内了。也就是说把上传成功后的文件存储到我本地文件内。然后上传成功后,我会返回一个json数据。

在项目中,我用到了如下几个插件:koa, fs, path, koa-router, koa-body, koa-static. 如上几个插件我们并不陌生哦。下面我们分别引用进来,如下代码:

const Koa = require('koa');
const fs = require('fs');
const path = require('path');
const router = require('koa-router')();
const koaBody = require('koa-body');
const static = require('koa-static');

const app = new Koa();

/* 
  koa-body 对应的API及使用 看这篇文章 http://www.ptbird.cn/koa-body.html
  或者看 github上的官网 https://github.com/dlau/koa-body
*/
app.use(koaBody({
  multipart: true, // 支持文件上传
  formidable: {
    maxFieldsSize: 2 * 1024 * 1024, // 最大文件为2兆
    multipart: true // 是否支持 multipart-formdate 的表单
  }
}));

app.use(static(path.join(__dirname)));

app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3001, () => {
  console.log('server is listen in 3001');
});

如上代码就是我app.js 基本架构,使用koa来监听服务,端口号是3001,然后使用koa-router来做路由页面指向。使用koa-body插件来解析post请求,及支持上传文件的功能。使用 koa-static插件来解析静态目录资源。使用fs来使用流的功能,比如 fs.createWriteStream 写文件 或 fs.createReadStream 读文件功能。使用path插件来解析目录问题,比如 path.join(__dirname) 这样的。

我们希望当我们 当我们访问 http://localhost:3001/ 的时候,希望页面指向 我们的 upload.html页面,因此app.js请求代码可以写成如下:

router.get('/', (ctx) => {
  // 设置头类型, 如果不设置,会直接下载该页面
  ctx.type = 'html';
  // 读取文件
  const pathUrl = path.join(__dirname, '/static/upload.html');
  ctx.body = fs.createReadStream(pathUrl);
});

注意:如上 ctx.type = 'html', 一定要设置下,否则打开该页面直接会下载该页面的了。然后我们使用fs.createReadStream来读取我们的页面后,把该页面指向 ctx.body 了,因此当我们访问 http://localhost:3001/ 的时候 就指向了 我们项目中的 static/upload.html 了。

下面我们来看下我们项目下的 /static/upload.html 页面代码如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <title>文件上传</title>
</head>
<body>
  <form action="http://localhost:3001/upload" method="post" enctype="multipart/form-data">
    <div>
      <input type="file" name="file">
    </div>
    <div>
      <input type="submit" value="提交"/>
    </div>
  </form>
</body>
</html>

如上upload.html页面,就是一个form表单页面,然后一个上传文件按钮,上传后,我们点击提交,即可调用form表单中的action动作调用http://localhost:3001

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值