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

前言

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

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

效果

前端部分

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文件上传、监听上传进度内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用nodejs+express实现简单的文件上传功能

    1.建立express项目 express -e nodejs-uploadfile 2.下载multer中间件 npm i multer or yarn multer 3.在routes/index.js中引用multer,由于还要使用到文件操作,还要引用fs模块,并指定文件上传目录 const multer = require('multer'); const fs = require('fs'); const UPLOAD_PATH = './uploads' 单文件上传: index.h

  • nodejs+express实现文件上传下载管理网站

    nodejs+express-实现文件上传下载管理的网站 项目Github地址:https://github.com/qcer/updo 后端:基于nodejs的express的web框架. 前端:bootstrap框架+vuejs.jquery等js库 功能点: dronzone.js实现文件拖拽上传.下载,可自定义传输容量. vuejs实现表格双向数据绑定. jquery.form.min.js表单插件,升级表单,实现表单提交回调. 纯css+jQuery实现一键返回顶部. 简单的ajax异

  • 基于nodejs+express(4.x+)实现文件上传功能

    Nodejs是一个年轻的编程框架,充满了活力和无限激情,一直都在保持着快速更新.基于Nodejs的官方Web开发库Express也在同步发展着,每年升级一个大版本,甚至对框架底层都做了大手术.在Express4时,替换掉中件间库connect,而改用多个更细粒度的库来取代.带来的好处是明显地,这些中间件能更自由的更新和发布,不会受到Express发布周期的影响:但问题也是很的棘手,不兼容于之前的版本,升级就意味着要修改代码. 通过一段时间的查阅资料.摸索,我发现实现上传的方式有:1.expres

  • Ajax异步文件上传与NodeJS express服务端处理

    为了避免在实现简单的异步文件上传功能时候引入一个第三方库文件的尴尬情形(库文件可能造成多余的开销,拉低应用加载速度,尤其是在引入库文件之后仅使用其中一两个功能的情况下,性价比极低),最近了解了一下文件异步上传的实现原理,顺带看了看进度条.图片预览等功能的实现,做一点简单的整理. 文件上传 HTML结构如下,一个file input和一个button.当点击"上传"按钮的时候,将file input选中的文件上传到服务器. <input type="file"

  • NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法

    实现多文件拖拽上传的简易Node项目,可以在github上下载,你可以先下载下来:https://github.com/Johnharvy/upLoadFiles/. 解开下载下的zip格式包,建议用webstom 运行该项目,通过app.js启动项目,如果提示找不到node.exe执行环境,请指定好你的node.exe安装位置.这里我用的express框架是3.21.2版本. 我们来简单介绍下拖拽效果是怎么实现的. 这里先看代码: <!DOCTYPE html> <html lang=

  • nodejs 终端打印进度条实例代码

    1. 场景导入 当我们对大量文件进行批量处理的时候(例如:上传/下载.保存.编译等),常常希望知道当前进展如何,或者失败(成功)的任务有多少:当我们的代码或程序已经发布,用户在执行安装的过程中,一个合适的(终端/命令行)进度条可以准确反映安装的步骤和进程,提升程序的可用性,一定程度缓解用户在等待中的烦恼-- 2. 基本原理 首先,在终端打印出文本是件比较容易的事情.那么使用简单的文本和符号,就够自己拼凑出命令行的效果(下面例子): 文件已上传: 43.60% ██████████████████

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

    前言 文件上传如果加上进度条会有更好的用户体验(尤其是中大型文件),本文使用 Nodejs 配合前端完成这个功能. 前端我们使用 FormData 来作为载体发送数据. 效果 前端部分 HTML 部分 和 Js 部分 <input type="file" id="file" /> <!-- 进度条 --> <progress id="progress" value="0" max="10

  • Spring boot + LayIM + t-io 实现文件上传、 监听用户状态的实例代码

    前言 今天的主要内容是:LayIM消息中图片,文件的上传对接.用户状态的监听.群在线人数的监听.下面我将挨个介绍. 图片上传 关于Spring boot中的文件上传的博客很多,我也是摘抄了部分代码.上传部分简单介绍,主要介绍在开发过程中遇到的问题.首先我们看一下LayIM的相应的接口: layim.config({ //上传图片接口 ,uploadImage: {url: '/upload/file'} //上传文件接口 ,uploadFile: {url: '/upload/file'} //

  • listview的上滑下滑监听,上下滑监听隐藏顶部选项栏的实例

    listview的上滑下滑监听,来隐藏和显示顶部选项栏的特效,京东 同程等APP的资源列表都有此特效. 两个重点: ①listview的setOnTouchListener监听方法 当滑动的Y位置减去按下的Y位置大于最小滑动距离时则为向下滑动 反之,当按下的Y位置减去滑动的Y位置大于最小滑动距离则为向上滑动 ②位移动画 就只要这两点需要注意的,直接上代码,注释很清楚. package com.example.android_topbar_gone; import java.util.ArrayL

  • zookeeper+Springboot实现服务器动态上下线监听教程详解

    目录 zookeeper+Springboot实现服务器动态上下线监听教程 一.什么是服务器动态上下线监听 二.为什么要实现对服务器上下线的监听 三.编码实现 四.测试 1.启动客户端,开启监听 2.按照下面的流程启动服务器端 zookeeper+Springboot实现服务器动态上下线监听教程 一.什么是服务器动态上下线监听 客户端能够实时洞察到服务器上下线的变化,现在我们看看下面三个变化给集群.服务器.客户端三者的变化 初始情况 服务器3启动 服务器2下线 从上面的图我们可以知道,在集群中,

  • java实现emqx设备上下线监听详解

    目录 正文 第一步,emqx配置aclz 第二步 代码中实现主题的订阅 在接受主题回调地方接受消息即可 正文 我们在做物联网项目的时候,需要实时的检测设备是否在线,emqx就为我们提供了一个很好的上下线监听机制,这里我就给大家讲一下,如何实现设备上下线的监听 emqx提供了系统主题进行监听 第一步,emqx配置aclz 增加默认系统监听 第二步 代码中实现主题的订阅 在接受主题回调地方接受消息即可 这里就实现了emq对设备的上下线监听啦,更多关于java emqx上下线监听的资料请关注我们其它相

  • Java可以如何实现文件变动的监听的示例

    应用中使用logback作为日志输出组件的话,大部分会去配置 `logback.xml` 这个文件,而且生产环境下,直接去修改logback.xml文件中的日志级别,不用重启应用就可以生效 那么,这个功能是怎么实现的呢? 应用中使用logback作为日志输出组件的话,大部分会去配置 logback.xml 这个文件,而且生产环境下,直接去修改logback.xml文件中的日志级别,不用重启应用就可以生效 那么,这个功能是怎么实现的呢? I. 问题描述及分析 针对上面的这个问题,首先抛出一个实际的

  • NodeJS多种创建WebSocket监听的方式(三种)

    WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术.在WebSocket API中,浏览器和服务器只需要要做一个握手(handshaking)的动作,然后,浏览器和服务器之间就形成了一条快速通道.两者之间就直接可以数据互相传送. WebSocket是一个通信的协议,分为服务器和客户端.服务器放在后台,保持与客户端的长连接,完成双方通信的任务.客户端一般都是实现在支持HTML5浏览器核心中,通过提供JavascriptAPI使用网页可以建立websocket连接.

  • JS实现移动端实时监听输入框变化的实例代码

    如果是在pc端,监听输入框你可能想到focus.blur.hover.onkeyup这些事件,但是如果是在移动端使用使用这些事件用户体验极差,因为你要用户收起键盘并且再点个空白处才生效,甚至还存在很大的兼容差异.那么怎么解决呢? 方案一 以前做一个简单的模糊搜索框的需求,大致思路是定义一个1s左右执行的定时器,定时器函数里面的逻辑是 判断文本框内容的长度,如果跟上一次长度有变化,就走一遍查询,如果没有变化不执行任何操作. 方案二 利用jquery提供的 input propertychange

  • JavaScript 监听组合按键思路及代码实现

    JavaScript监听组合按键 1. 思路 如图,通过监听并打印键盘keydown事件,得到图示内容,观察发现, 当按下的组合键包含Ctrl键时,ctrlKey键会显示为true; 当按下的组合键包含Shift键.或者按键之前开启大写时,shiftkey键会显示为true; 当按下的组合键包含Alt键时,altKey键会显示为true; 当按下的组合键包含meta键(Mac电脑上 是 [⌘].command键,非mac电脑为 是win键时,metaKey键会显示为true 另外,按下键时,可通

  • 使用vue与jquery实时监听用户输入状态的操作代码

    实现效果:input未输入值,按钮禁用 jquery操作代码: html <input type="text" name="" placeholder="请输入用户名" id="userName" > <button class="disabled" id="login">登录</button> css .disabled { pointer-even

随机推荐