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中简单实现Javascript Promise机制的实例
Dec 06 NodeJs
PHP和NodeJs开发的应用如何共用Session
Apr 16 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
Aug 16 NodeJs
nodejs根据ip数组在百度地图中进行定位
Mar 06 NodeJs
详解Windows下安装Nodejs步骤
May 18 NodeJs
详解nodejs中express搭建权限管理系统
Sep 15 NodeJs
Nodejs+express+ejs简单使用实例代码
Sep 18 NodeJs
nodejs实现OAuth2.0授权服务认证
Dec 27 NodeJs
nodejs微信开发之授权登录+获取用户信息
Mar 17 NodeJs
NodeJS有难度的面试题(能答对几个)
Oct 09 NodeJs
浅谈Node的内存泄露问题
May 06 NodeJs
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
May 30 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使用range协议实现输出文件断点续传代码实例
2014/07/04 PHP
php中in_array函数用法分析
2014/11/15 PHP
在PHP程序中使用Rust扩展的方法
2015/07/03 PHP
Aster vs KG BO3 第一场2.18
2021/03/10 DOTA
了解jQuery技巧来提高你的代码
2010/01/08 Javascript
使用jQuery解决IE与FireFox下createElement方法的差异
2013/11/14 Javascript
JS获取url链接字符串 location.href
2013/12/23 Javascript
JS控制网页动态生成任意行列数表格的方法
2015/03/09 Javascript
javascript实现数组内值索引随机化及创建随机数组的方法
2015/08/10 Javascript
javascript实现任务栏消息提示的简单实例
2016/05/31 Javascript
jQuery实现查找链接文字替换属性的方法
2016/06/27 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
JavaScript设计模式之代理模式详解
2017/06/09 Javascript
vue中设置height:100%无效的问题及解决方法
2018/07/27 Javascript
微信小程序url传参写变量的方法
2018/08/09 Javascript
微信小程序下拉框功能的实例代码
2018/11/06 Javascript
详解vuex持久化插件解决浏览器刷新数据消失问题
2019/04/15 Javascript
js/jQuery实现全选效果
2019/06/17 jQuery
详解json串反转义(消除反斜杠)
2019/08/12 Javascript
vue实现简易图片左右旋转,上一张,下一张组件案例
2020/07/31 Javascript
vue实现两个组件之间数据共享和修改操作
2020/11/12 Javascript
[01:00:54]TI4正赛第二日开场
2014/07/20 DOTA
python中List的sort方法指南
2014/09/01 Python
Python自动调用IE打开某个网站的方法
2015/06/03 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
2016/09/21 Python
Python3 使用pillow库生成随机验证码
2019/08/26 Python
python 引用传递和值传递详解(实参,形参)
2020/06/05 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
HTML5的新特性(1)
2016/03/03 HTML / CSS
美国隐形眼镜网上商店:Lens.com
2019/09/03 全球购物
数据库基础的一些面试题
2012/02/25 面试题
服务生自我鉴定
2014/01/22 职场文书
《一个中国孩子的呼声》教学反思
2014/02/12 职场文书
社区网格化管理实施方案
2014/03/21 职场文书
伦敦奥运会的口号
2014/06/21 职场文书
男方婚前保证书
2015/02/28 职场文书