node笔记_express结合formidable实现前后端的文件上传
文章目录
- ⭐前言
- ⭐安装http请求的文件解析依赖库
- 💖 安装 formidable
- 💖 node formidable接受formData上传参数
- ⭐上传的页面搭建
- 💖 vue2 element upload
- 💖 node 渲染 上传文件
- ⭐后端生成api上传文件到指定目录
- 💖完整的代码块
- 💖效果图
- ⭐结束
⭐前言
大家好,我是yma16,本期分享node使用express结合formidable实现前后端联调的文件上传
往期文章
node_windows环境变量配置
node_npm发布包
linux_配置node
node_nvm安装配置
node笔记_http服务搭建(渲染html、json)
node笔记_读文件
node笔记_写文件
node笔记_连接mysql实现crud
⭐安装http请求的文件解析依赖库
💖 安装 formidable
$ npm install formidable
💖 node formidable接受formData上传参数
查看 readme的介绍

const hostname = '127.0.0.1';
const port = 3000;
const express = require("express");
const formidable = require('formidable');
const app = express();
app.listen(port, hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
});
app.get("/", (req, res) => {console.log(__dirname)res.json({code: 200,data: 'yma16 blog',msg: 'csdn node challenge'})
});app.post('/uploadFile/action', (req, res, next) => {// parse a file uploadconst form = new formidable({multiples: true});// parse 解析form.parse(req, (err, fields, files) => {console.log('req', req)console.log('err,', err)console.log('fields,', fields)console.log('files,', files)if (err) {next(err);return;}// json返回res.json({fields,files});})
})
⭐上传的页面搭建
使用formData上传二进制文件
💖 vue2 element upload
这里使用vue2和element实现上传
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>elementui vue2 上传文件</title><!-- vue2 生产环境版本,优化了尺寸和速度 --><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><!-- 引入样式 --><link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"><!-- 引入组件库 --><script src="https://unpkg.com/element-ui/lib/index.js"></script><!-- axios --><script src="https://unpkg.com/axios/dist/axios.min.js"></script></head><style>#app {position: absolute;height: 100vh;width: 100vw;}.upload-container {position: relative;width: 100%;height: 100%;}.upload-container-box {position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);}.container-title {position: relative;width: 100%;font-size: 24px;font-weight: bold;text-align: center;}</style><body><div id="app"><div class="container-title">{{ message }}</div><div><!-- 文件上传 先关闭自动上传--><div class="upload-container-box"><template><!-- :action="uploadForm.uploadUrl"--><el-upload class="upload-demo" :accept="uploadForm.accept" ref="uploadRef" drag:onRemove="handleRemove" :onChange="handlChange" :beforeUpload="beforeUpload":action="uploadForm.uploadUrl" :autoUpload="uploadForm.autoUpload":fileList="uploadForm.fileList" list-type="picture" :httpRequest="designUpload"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip">只能上传单个png、jpg文件</div></el-upload><div style="text-align: center"><el-button type="primary" plain @click="submitBtn"style="margin-top:10px">上传到服务器</el-button></div></template></div></div></div><script type="text/javascript">// ELEMENT.Messageconst {Message}=Element;// instanceconst instanceVue = {el: '#app',name:'upload-component',data() {const uploadTypeForm = {text: ["jpg", "png", "jpeg", "svg"]};return {message: 'element 自定义上传',$message:Message,uploadForm: {autoUpload: false,accept: uploadTypeForm.text.join(","),uploadUrl: "http://localhost:3000/uploadFile/action", //上传的url 默认空fileList: []}};},methods: {/*** 文件删除回调*/handleRemove(file, fileList) {this.uploadForm.fileList = fileList;},/*** 选择文件时回调*/handlChange(file, fileList) {this.uploadForm.fileList = fileList;},//上传前的回调beforeUpload: function(file) {console.info("上传前的钩子", file);// 关闭自动上传return false},submitBtn() {if (this.uploadForm.fileList.length <= 0) {this.$message({message: "请先选择文件!",type: "error"});}this.$refs.uploadRef.submit(); //触发自定义上传},//自定义上传designUpload(params) {console.info("自定义上传", params);const that = this;const formData = new FormData();formData.append("file", params.file);const header = {"Content-Type": "mutipart/form-data"};//上传的后端接口const upLoadUrl = that.uploadForm.upLoadUrl;axios({url: upLoadUrl,method: "post",data: formData,headers: header}).then(res => {console.info("res", res);params.onSuccess(); //成功iconthat.$message({message: "上传成功!",type: "success"});}).catch(r => {that.$message.error("上传失败!");throw Error(r);});}},}// 实例化new Vue(instanceVue);</script></body>
</html>
上传file参数是二进制文件

💖 node 渲染 上传文件
const hostname = '127.0.0.1';
const port = 3000;
const express = require("express");
const app = express();app.listen(port,hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
});
// server your css as static
app.use(express.static(__dirname));app.get("/", (req, res) => {res.json({code:200,data:'yma16 blog',msg:'csdn node challenge'})
});
app.get("/uploadFile", (req, res) => {res.sendFile(__dirname + "/html/upload.html");
});
渲染 upload.html

⭐后端生成api上传文件到指定目录
- 先渲染html的上传页面
- 接受文件参数
- 处理文件名,避免重名,加上时间撮处理
💖完整的代码块
指定 media为上传路径,生成文件名加上时间搓
const hostname = '127.0.0.1';
const port = 3000;const express = require("express");
const formidable = require('formidable');
const fs = require('fs')
const app = express();app.listen(port, hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
});
// server your css as static
app.use(express.static(__dirname));app.get("/", (req, res) => {console.log(__dirname)res.json({code: 200,data: 'yma16 blog',msg: 'csdn node challenge'})
});app.get("/uploadFile", (req, res) => {console.log(__dirname)res.sendFile(__dirname + "/html/upload.html");
});function generateFilename(oldFilename) {//将老的文件名拼上时间戳let d = new Date();let names = oldFilename.split(".");return `${names[0]}_${""+d.getFullYear() + (d.getMonth()+1) + d.getDate() +'_'+ d.getHours() + d.getMinutes() + d.getSeconds()}.${names[1]}`;
}app.post('/uploadFile/action', (req, res, next) => {// parse a file upload// const form = new formidable({multiples: true});// api回调const form = new formidable.IncomingForm();//保持原有扩展名form.keepExtensions = true;//设置上传目录form.uploadDir = __dirname + "/media/";// parse 解析form.parse(req, async(err, fields, files) => {console.log('req', req)console.log('err,', err)console.log('fields,', fields)console.log('files,', files)if (err) {next(err);return;}try {console.log('files.file', files.file)// 默认名称const originalFilename = files.file.originalFilename;// 默认的路径const filePath= files.file.filepath//重命名上传的文件fs.rename(filePath, form.uploadDir + generateFilename(originalFilename), err => {if (err) {console.log("重命名失败");console.log(err);} else {console.log("重命名成功!");}})} catch (r) {next(r)return}// json返回res.json({fields,files});})
})
得到的文件流对象

💖效果图
前端的接口联调

后端node处理生成的文件

⭐结束
感谢阅读💖,如有不足欢迎指出!

相关文章:
node笔记_express结合formidable实现前后端的文件上传
文章目录 ⭐前言⭐安装http请求的文件解析依赖库💖 安装 formidable💖 node formidable接受formData上传参数 ⭐上传的页面搭建💖 vue2 element upload💖 node 渲染 上传文件 ⭐后端生成api上传文件到指定目录💖完整的…...
CKA 09_Kubernetes工作负载与调度 资源调度 三类QoS request 资源需求 limit 资源限额
文章目录 1. 资源调度1.1 准备工作1.2 为什么需要 request 和 limit1.3 内存限制1.3.1 Brustable1.3.2 Guaranteed1.3.3 BestEffort1.3.4 当容器申请的资源超出 limit 和 request 1.4 CPU限制 1. 资源调度 1.1 准备工作 Kubernetes 采用 request 和 limit 两种限制类型来对资源…...
【pytorch】维度变换
【pytorch】维度变换 View操作unSqueeze操作图片处理的一个案例squeeze 维度删减操作维度扩展-expand维度扩展-repeat矩阵的转置操作-transpose View操作 将一个四维的张量(b x c x h x w)转换成一个二维的张量 对于四张图片 将每一张图像用一行向量进…...
vue3中的nextTick()
目录 nextTick() 方法用法回调函数方式使用await方式使用 实现原理使用nextTick() 方法时的注意事项 nextTick() 方法 nextTick() 方法是一个非常强大的工具,是一个等待下一次 DOM 更新刷新的工具方法。用于将一个函数以异步的方式推迟到下一个 DOM 更新周期执行。…...
高效学习传感器|霍尔式传感器
01、霍尔式传感器的工作原理 1●霍尔效应 霍尔式传感器的物理基础是霍尔效应。如图1所示,在一块长度为l、宽度为b、厚度为d的长方体导电板上,左、右、前、后侧面都安装上电极。在长度方向上通入电流I,在厚度方向施加磁感应强度为B的磁场。 ■…...
2023年前端面试高频考点HTML5+CSS3
目录 浏览器的渲染过程⭐⭐⭐ CSS 、JS 阻塞 DOM 解析和渲染 回流(重排)和重绘⭐⭐ 选择器 ID选择器、类选择器、标签选择器(按优先级高到低排序)⭐⭐ 特殊符号选择器(>,,~,空格࿰…...
企业开源测试项目实战(附全套实战项目教程+视频+源码)
接口测试项目 1. No matching distribution found for itypes1.1.0 Could not find a version that satisfies the requirement itypes1.1.0 (from -r requirements.txt (line 8)) (from versions: ) No matching distribution found for itypes1.1.0 (from -r requirements.…...
信创办公–基于WPS的EXCEL最佳实践系列 (创建表格)
信创办公–基于WPS的EXCEL最佳实践系列 (创建表格) 目录 应用背景操作步骤1、新建空白工作簿并命名为“奖牌榜”2、使用模板新建工作簿3、新增一张工作表,并将工作簿的标签更改为红色4、复制与隐藏工作表5、添加工作簿属性值6、更改工作簿主题…...
四、HAL_驱动机械按键
1、开发环境。 (1)KeilMDK:V5.38.0.0 (2)STM32CubeMX:V6.8.1 (3)MCU:STM32F407ZGT6 2、机械按键简介 (1)按键内部是机械结构,也就是内部是没有电路的。按键按下内部引脚导通,松开内部断开。 3、实验目的&原理…...
机器学习实战六步法之数据收集方法(四)
要落地一个机器学习的项目,是有章可循的,通过这六个步骤,小白也能搞定机器学习。 看我闪电六连鞭!🤣 数据收集 数据是机器学习的基础,没有数据一切都是空谈!数据集的数据量和数据的质量往往决…...
神经网络:CNN中的filter,kernel_size,strides,padding对输出形状的影响
输入数据在经过卷积层后,形状一般会发生改变,而形状的变化往往与以下四个超参数有关。 1,filter(out_channel) 该超参数控制着输入数据经过卷积层中需要与几个卷积核进行运算,而输入数据与每个卷积核进行…...
Spring Boot集成Redisson布隆过滤器案例
1 什么是布隆过滤器 布隆过滤器实际上是一个非常长的二进制向量(bitmap)和一系列随机哈希函数。那什么又叫哈希函数呢?哈希函数指将哈希表中元素的关键键值通过一定的函数关系映射为元素存储位置的函数。(HashMap源码) 布隆过滤器的优点&…...
使用 VSCode SSH 公网远程连接本地服务器开发 - cpolar内网穿透
文章目录 前言视频教程1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 转…...
portraiture宿主插件最新v4中文版本下载及使用教程
自拍怎么可以不修图呢?如果要修图的话,磨皮就是其中非常重要的一环。皮肤看起来细腻光滑了,整个人的颜值都会瞬间拉高。下面就让我们介绍一下磨皮用什么软件好用,什么软件可以手动磨皮的相关内容。portraiture是ps人像修图中常用的…...
一. ATR技术指标的定义与运用
一. ATR的定义 1. 什么是ATR ATR英文全名是Average true range,翻译过来就是平均真实波幅,这个指标主要用来衡量最近N天TR(真实波幅)的平均值。 2. ATR相关计算公式 T R [ ( 最高价 − 最低价 ) , ( 前一次收盘价 − 最高价 ) ࿰…...
linux find帮助文档
以下是完整的find命令帮助文档: 用法:find [-H] [-L] [-P] [-D debugopts] [-Olevel] [起始路径…] [表达式] 选项: -H 跟随命令行符号链接 -L 跟随所有符号链接 -P 不跟随任何符号链接(默认) -D debugopts 调试标志…...
搜索与图论(acwing算法基础)
文章目录 DFS排列数字n皇后 BFS走迷宫 拓扑序列单链表树与图的深度优先搜索模拟队列有向图的拓扑序列 bellman-ford有边数限制的最短路 spfaspfa求最短路spfa判断负环 FloydFloyd求最短路 PrimPrim算法求最小生成树 KruskalKruskal算法求最小生成树 染色法判定二分图染色法判定…...
【数据结构】何为数据结构。
🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星T…...
【P57】JMeter 保存响应到文件(Save Responses to a file)
文章目录 一、保存响应到文件(Save Responses to a file)参数说明二、准备工作三、测试计划设计 一、保存响应到文件(Save Responses to a file)参数说明 可以将结果树保存到文件 使用场景:当结果太大,使…...
Visual Studio 2022 v17.6 正式发布
Visual Studio 17.6 正式发布,这个最新版本提供了一系列强大的工具和功能,旨在使你能够制作出最先进的应用程序。 提高生产力 通过 Visual Studio 2022,目标是帮助你在更短的时间内完成 IDE 内的所有开发任务,在这个版本中&…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
