当前位置: 首页 > 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;在这个版本中&…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...