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 win7下安装方法
May 24 NodeJs
nodejs简单实现中英文翻译
May 04 NodeJs
nodejs实现发出蜂鸣声音(系统报警声)的方法
Jan 18 NodeJs
win系统下nodejs环境安装配置
May 04 NodeJs
nodejs批量下载图片的实现方法
May 19 NodeJs
nodejs结合socket.io实现websocket通信功能的方法
Jan 12 NodeJs
通过nodejs 服务器读取HTML文件渲染到页面的方法
May 17 NodeJs
详解Nodejs mongoose
Jun 10 NodeJs
深入理解nodejs搭建静态服务器(实现命令行)
Feb 05 NodeJs
nodejs使用Sequelize框架操作数据库的实现
Oct 21 NodeJs
nodejs+koa2 实现模仿springMVC框架
Oct 21 NodeJs
NodeJs内存占用过高的排查实战记录
May 10 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 $_ENV为空的原因分析
2009/06/01 PHP
分享一个PHP数据流应用的简单例子
2012/06/01 PHP
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
php运行时动态创建函数的方法
2015/03/16 PHP
PHP中$_SERVER使用说明
2015/07/05 PHP
解决JS中乘法的浮点错误的方法
2014/01/03 Javascript
JS 弹出层 定位至屏幕居中示例
2014/05/21 Javascript
javascript实现阻止iOS APP中的链接打开Safari浏览器
2014/06/12 Javascript
Node.js编码规范
2014/07/14 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
基于Vue2.0的分页组件
2017/03/16 Javascript
webpack使用 babel-loader 转换 ES6代码示例
2017/08/21 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
ReactNative中使用Redux架构总结
2017/12/15 Javascript
解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
2018/09/25 Javascript
微信小程序CSS3动画下拉菜单效果
2018/11/04 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
python条件变量之生产者与消费者操作实例分析
2017/03/22 Python
Python实现连接postgresql数据库的方法分析
2017/12/27 Python
面向对象设计的原则是什么
2013/02/13 面试题
求职简历自荐信范文
2013/10/21 职场文书
生物专业个人自荐信范文
2013/11/29 职场文书
《争吵》教学反思
2014/02/15 职场文书
征婚广告词
2014/03/17 职场文书
经贸日语专业个人求职信范文
2014/04/29 职场文书
五水共治捐款倡议书
2014/05/14 职场文书
疾病防治方案
2014/05/31 职场文书
公司委托书格式
2014/08/01 职场文书
离职证明标准格式
2014/09/15 职场文书
成本会计实训报告
2014/11/05 职场文书
2015入党自荐书范文
2015/03/05 职场文书
活动主持人开场白
2015/05/28 职场文书
运动会广播稿50字
2015/08/19 职场文书
幼儿园大班开学寄语(2016秋季)
2015/12/03 职场文书
python实现简易自习室座位预约系统
2021/06/30 Python
一文搞清楚MySQL count(*)、count(1)、count(col)区别
2022/03/03 MySQL