Nodejs文件上传、监听上传进度的代码


Posted in NodeJs onMarch 27, 2020

前言

文件上传如果加上进度条会有更好的用户体验(尤其是中大型文件),本文使用 Nodejs 配合前端完成这个功能。

前端我们使用 FormData 来作为载体发送数据。

效果 

Nodejs文件上传、监听上传进度的代码 

前端部分

HTML 部分 和 Js 部分

<input type="file" id="file" />
<!-- 进度条 -->
<progress id="progress" value="0" max="100"></progress>
// 获取 input file 的 dom 对象
const inputFile = document.querySelector('#file');

// 监听 change 事件
inputFile.addEventListener('change', function() {
 // 使用 formData 装载 file
 const formData = new FormData();
 formData.append('file', this.files[0]);
 
 // 上传文件
 upload(formData);
})

下面我们实现 upload 方法。

使用 XMLHttpRequest 的方式

const upload = ( formData ) => {
 const xhr = new XMLHttpRequest();
 // 监听文件上传进度
 xhr.upload.addEventListener('progress', function(e) {
 if (e.lengthComputable) {
 // 获取进度
 const progress = Math.round((e.loaded * 100) / e.total);
 
 document.querySelector('#progress').setAttribute('value', progress);
 }
 },false);
 
 // 监听上传完成事件
 xhr.addEventListener('load', ()=>{
 console.log(':smile:上传完成')
 }, false);
 
 xhr.open('post', 'http://127.0.0.1:3000/upload');
 xhr.send(formData); 
}

使用 jQuery 的 ajax 上传

jQuery 目前的使用量依然庞大,那么使用 jQuery 的 ajax 如何监听文件上传进度呢:

const upload = ( formData ) => {
 $.ajax({
 type: 'post',
 url: 'http://127.0.0.1:3000/upload',
 data: formData,
 // 不进行数据处理和内容处理
 processData: false,
 contentType: false,
 // 监听 xhr
 xhr: function() {
  const xhr = $.ajaxSettings.xhr();
  if (xhr.upload) {
  xhr.upload.addEventListener('progress', e => {
  const { loaded, total } = e;
  var progress = (loaded / total) * 100;
  document.querySelector('#progress').setAttribute('value', progress);
  },
  false
  );
  return xhr;
  }
 },
 success: function(response) {
  console.log('上传成功');
 }
 });
}

使用 axios 上传并监听进度

axios 使用量非常大,用它监听文件上传更简单,代码如下:

const upload = async ( formData ) => {

 let config = {
 // 注意要把 contentType 设置为 multipart/form-data
 headers: {
  'Content-Type': 'multipart/form-data'
 },
 
 // 监听 onUploadProgress 事件
 onUploadProgress: e => {
  const {loaded, total} = e;
  // 使用本地 progress 事件
  if (e.lengthComputable) {
  let progress = loaded / total * 100;
  document.querySelector('#progress').setAttribute('value', progress);
  }
 }
 };

 const { status } = await axios.post('http://127.0.0.1:3000/upload', formData, config);
 if (res.status === 200) {
  console.log('上传完成:grinning:');
 }
}

Nodejs 部分

这部分比较简单,其实就是单纯的文件上传,我们用 Koa 来实现.

环境搭建及依赖包安装

这里使用 koa2 ,安装以下依赖包:

  • koa
  • @koa/router: koa 的路由
  • @koa/cors:用于跨域
  • koa-body: 解析 body 数据
  • nodemon: 使用它启动服务,带有热更新

代码部分

const Koa = require('koa');
const Router = require('@koa/router');
const koaBody = require('koa-body');
const path = require('path');
const fs = require('fs');
const cors = require('@koa/cors');

const app = new Koa();
const router = new Router();

router.all('/upload', async ctx => {
 // 处理文件上传 
 const res = await dealFile(ctx);

 res && (ctx.body = {
 status: 200,
 msg: 'complete'
 });
});

// 中间件部分
app.use(cors());
app.use(
 koaBody({
 multipart: true,
 formidable: {
 maxFileSize: 2000 * 1024 * 1024 //最大2G
 }
 })
);
app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3000);

dealFile 方法处理上传的文件

出于性能考虑,操作 file 毫无疑问要使用 stream 。

我们要监听文件流 end 事件,由于无法在事件回调里返回响应,因为会报 404,所以需要使用 Promise 来封装一下,然后用 async、await

const dealFile = ctx => {
 const { file } = ctx.request.files;

 const reader = fs.createReadStream(file.path);
 const writer = fs.createWriteStream(
 // 文件上传到 image 文件夹中
 path.resolve(__dirname, './image', file.name)
 );

 return new Promise((resove, reject) => {
 
 reader.pipe(writer);
 
 reader.on('end', () => {
 resove(true);
 });
 
 reader.on('error', err => {
 throw err;
 })
 
 });
};

到这里就全部完成了。

这里注意一下:前端监听文件进度不需要后端有什么特殊处理,后端仅仅是做了文件流的写入而已。

总结

到此这篇关于Nodejs文件上传、监听上传进度的文章就介绍到这了,更多相关Nodejs文件上传、监听上传进度内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

NodeJs 相关文章推荐
nodejs教程之异步I/O
Nov 21 NodeJs
nodejs个人博客开发第五步 分配数据
Apr 12 NodeJs
NodeJs安装npm包一直失败的解决方法
Apr 28 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 NodeJs
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
Sep 06 NodeJs
使用vs code开发Nodejs程序的使用方法
Sep 21 NodeJs
nodejs实现超简单生成二维码的方法
Mar 17 NodeJs
nodejs aes 加解密实例
Oct 10 NodeJs
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
Oct 17 NodeJs
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
Mar 02 NodeJs
NodeJS有难度的面试题(能答对几个)
Oct 09 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 #NodeJs
nodejs脚本centos开机启动实操方法
Mar 04 #NodeJs
nodejs制作小爬虫功能示例
Feb 24 #NodeJs
nodejs使用socket5进行代理请求的实现
Feb 21 #NodeJs
linux 下以二进制的方式安装 nodejs
Feb 12 #NodeJs
nodejs实现百度舆情接口应用示例
Feb 07 #NodeJs
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
Feb 06 #NodeJs
You might like
php.ini中date.timezone设置分析
2011/07/29 PHP
php重定向的三种方法分享
2012/02/22 PHP
thinkphp实现数组分页示例
2014/04/13 PHP
ASP中Sub和Function的区别说明
2020/08/30 Javascript
jquery调用asp.net 页面后台的实现代码
2011/04/27 Javascript
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
jQuery的选择器中的通配符使用介绍
2014/03/20 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
2016/06/10 Javascript
canvas实现探照灯效果
2017/02/07 Javascript
jquery实现页面加载效果
2017/02/21 Javascript
详解vue过滤器在v2.0版本用法
2017/06/01 Javascript
基于JavaScript实现图片连播和联级菜单实例代码
2017/07/28 Javascript
Node.JS循环删除非空文件夹及子目录下的所有文件
2018/03/12 Javascript
详解Vue CLI 3.0脚手架如何mock数据
2018/11/23 Javascript
Element-UI中Upload上传文件前端缓存处理示例
2019/02/21 Javascript
vue如何实现自定义底部菜单栏
2019/07/01 Javascript
element-ui tree结构实现增删改自定义功能代码
2020/08/31 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
[02:23]完美世界全国高校联赛街访DOTA2第一期
2019/11/28 DOTA
python让图片按照exif信息里的创建时间进行排序的方法
2015/03/16 Python
python使用装饰器和线程限制函数执行时间的方法
2015/04/18 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
JS设计模式之责任链模式实例详解
2018/02/03 Python
python实现ID3决策树算法
2018/08/29 Python
对Keras中predict()方法和predict_classes()方法的区别说明
2020/06/09 Python
用opencv给图片换背景色的示例代码
2020/07/08 Python
用canvas画心电图的示例代码
2018/09/10 HTML / CSS
Get The Label中文官网:英国运动时尚购物平台
2017/04/19 全球购物
大学考试作弊检讨书
2014/01/30 职场文书
信息技术教学反思
2014/02/12 职场文书
六查六看剖析材料
2014/02/15 职场文书
离婚协议书怎么写2014
2014/09/30 职场文书
2014年宣传部个人工作总结
2014/12/06 职场文书
疾病证明书
2015/06/19 职场文书
python中 .npy文件的读写操作实例
2022/04/14 Python