当前位置: 首页 > news >正文

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的介绍
formidable

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参数是二进制文件
file-upload

💖 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
upload.html

⭐后端生成api上传文件到指定目录

  1. 先渲染html的上传页面
  2. 接受文件参数
  3. 处理文件名,避免重名,加上时间撮处理

💖完整的代码块

指定 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处理生成的文件

上传的文件

⭐结束

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

blue-sky-water

相关文章:

node笔记_express结合formidable实现前后端的文件上传

文章目录 ⭐前言⭐安装http请求的文件解析依赖库&#x1f496; 安装 formidable&#x1f496; node formidable接受formData上传参数 ⭐上传的页面搭建&#x1f496; vue2 element upload&#x1f496; node 渲染 上传文件 ⭐后端生成api上传文件到指定目录&#x1f496;完整的…...

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操作 将一个四维的张量&#xff08;b x c x h x w&#xff09;转换成一个二维的张量 对于四张图片 将每一张图像用一行向量进…...

vue3中的nextTick()

目录 nextTick() 方法用法回调函数方式使用await方式使用 实现原理使用nextTick() 方法时的注意事项 nextTick() 方法 nextTick() 方法是一个非常强大的工具&#xff0c;是一个等待下一次 DOM 更新刷新的工具方法。用于将一个函数以异步的方式推迟到下一个 DOM 更新周期执行。…...

高效学习传感器|霍尔式传感器

01、霍尔式传感器的工作原理 1●霍尔效应 霍尔式传感器的物理基础是霍尔效应。如图1所示&#xff0c;在一块长度为l、宽度为b、厚度为d的长方体导电板上&#xff0c;左、右、前、后侧面都安装上电极。在长度方向上通入电流I&#xff0c;在厚度方向施加磁感应强度为B的磁场。 ■…...

2023年前端面试高频考点HTML5+CSS3

目录 浏览器的渲染过程⭐⭐⭐ CSS 、JS 阻塞 DOM 解析和渲染 回流&#xff08;重排&#xff09;和重绘⭐⭐ 选择器 ID选择器、类选择器、标签选择器&#xff08;按优先级高到低排序&#xff09;⭐⭐ 特殊符号选择器&#xff08;&#xff1e;,,~&#xff0c;空格&#xff0…...

企业开源测试项目实战(附全套实战项目教程+视频+源码)

接口测试项目 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最佳实践系列 &#xff08;创建表格&#xff09; 目录 应用背景操作步骤1、新建空白工作簿并命名为“奖牌榜”2、使用模板新建工作簿3、新增一张工作表&#xff0c;并将工作簿的标签更改为红色4、复制与隐藏工作表5、添加工作簿属性值6、更改工作簿主题…...

四、HAL_驱动机械按键

1、开发环境。 (1)KeilMDK&#xff1a;V5.38.0.0 (2)STM32CubeMX&#xff1a;V6.8.1 (3)MCU&#xff1a;STM32F407ZGT6 2、机械按键简介 (1)按键内部是机械结构&#xff0c;也就是内部是没有电路的。按键按下内部引脚导通&#xff0c;松开内部断开。 3、实验目的&原理…...

机器学习实战六步法之数据收集方法(四)

要落地一个机器学习的项目&#xff0c;是有章可循的&#xff0c;通过这六个步骤&#xff0c;小白也能搞定机器学习。 看我闪电六连鞭&#xff01;&#x1f923; 数据收集 数据是机器学习的基础&#xff0c;没有数据一切都是空谈&#xff01;数据集的数据量和数据的质量往往决…...

神经网络:CNN中的filter,kernel_size,strides,padding对输出形状的影响

输入数据在经过卷积层后&#xff0c;形状一般会发生改变&#xff0c;而形状的变化往往与以下四个超参数有关。 1&#xff0c;filter&#xff08;out_channel&#xff09; 该超参数控制着输入数据经过卷积层中需要与几个卷积核进行运算&#xff0c;而输入数据与每个卷积核进行…...

Spring Boot集成Redisson布隆过滤器案例

1 什么是布隆过滤器 布隆过滤器实际上是一个非常长的二进制向量(bitmap)和一系列随机哈希函数。那什么又叫哈希函数呢&#xff1f;哈希函数指将哈希表中元素的关键键值通过一定的函数关系映射为元素存储位置的函数。&#xff08;HashMap源码&#xff09; 布隆过滤器的优点&…...

使用 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中文版本下载及使用教程

自拍怎么可以不修图呢&#xff1f;如果要修图的话&#xff0c;磨皮就是其中非常重要的一环。皮肤看起来细腻光滑了&#xff0c;整个人的颜值都会瞬间拉高。下面就让我们介绍一下磨皮用什么软件好用&#xff0c;什么软件可以手动磨皮的相关内容。portraiture是ps人像修图中常用的…...

一. ATR技术指标的定义与运用

一. ATR的定义 1. 什么是ATR ATR英文全名是Average true range&#xff0c;翻译过来就是平均真实波幅&#xff0c;这个指标主要用来衡量最近N天TR(真实波幅)的平均值。 2. ATR相关计算公式 T R [ ( 最高价 − 最低价 ) &#xff0c; ( 前一次收盘价 − 最高价 ) &#xff0…...

linux find帮助文档

以下是完整的find命令帮助文档&#xff1a; 用法&#xff1a;find [-H] [-L] [-P] [-D debugopts] [-Olevel] [起始路径…] [表达式] 选项&#xff1a; -H 跟随命令行符号链接 -L 跟随所有符号链接 -P 不跟随任何符号链接&#xff08;默认&#xff09; -D debugopts 调试标志…...

搜索与图论(acwing算法基础)

文章目录 DFS排列数字n皇后 BFS走迷宫 拓扑序列单链表树与图的深度优先搜索模拟队列有向图的拓扑序列 bellman-ford有边数限制的最短路 spfaspfa求最短路spfa判断负环 FloydFloyd求最短路 PrimPrim算法求最小生成树 KruskalKruskal算法求最小生成树 染色法判定二分图染色法判定…...

【数据结构】何为数据结构。

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星T…...

【P57】JMeter 保存响应到文件(Save Responses to a file)

文章目录 一、保存响应到文件&#xff08;Save Responses to a file&#xff09;参数说明二、准备工作三、测试计划设计 一、保存响应到文件&#xff08;Save Responses to a file&#xff09;参数说明 可以将结果树保存到文件 使用场景&#xff1a;当结果太大&#xff0c;使…...

Visual Studio 2022 v17.6 正式发布

Visual Studio 17.6 正式发布&#xff0c;这个最新版本提供了一系列强大的工具和功能&#xff0c;旨在使你能够制作出最先进的应用程序。 提高生产力 通过 Visual Studio 2022&#xff0c;目标是帮助你在更短的时间内完成 IDE 内的所有开发任务&#xff0c;在这个版本中&…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...