news 2026/6/1 9:15:51

Vue3+Node.js实现文件上传并发控制与安全防线 进阶篇

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3+Node.js实现文件上传并发控制与安全防线 进阶篇

上一篇我们实现了最基础的 FormData 上传,体会了前后端的基础联调。但如果在面试中被问到:“如果用户上传了一个 10GB 的文件怎么办?”或者“用户同时选了 100 张图片,浏览器卡死怎么办?”这就需要用到进度监听、双端校验与并发控制。

1 核心概念

文件校验
需要遵循“前端防误操作,后端防恶意攻击”的原则,分为三个层级:

  • 第一层:前端 JS 校验 通过 input 标签属性和 JavaScript 读取 file.size 与 file.type。

  • 第二层:后端请求头校验 使用 Node.js 的 multer 中间件,读取 HTTP 请求头中的 Content-Type 和限制文件流大小。能拦截超大文件,防止服务器内存溢出。

  • 第三层:文件二进制校验 读取文件底层二进制数据的前 8 个字节,与标准文件类型的十六进制码进行比对。这是最高级别的安全校验。无论用户怎么改后缀、改请求头,文件底层的二进制编码是无法伪造的。

并发控制
如果不做控制,直接通过 Promise.all 一次性发送 100 个文件,会导致两个严重问题:

  • 浏览器 TCP 连接限制, Chrome 浏览器规定,对同一个域名最多只能同时维持 6 个网络连接。多出的 94
    个请求会被强制挂起(Pending)。排队时间过长会导致后面的请求直接超时(Timeout)断开。

  • 前端内存占用过高100 个大文件的 FormData 实例会瞬间占满内存,触发浏览器垃圾回收(GC),直接导致页面卡死。

2 前端实现:进度条与取消请求

我们需要使用 Axios/XHR 而不是 fetch, 因为 fetch 具有局限性。fetch API 设计上不支持监听上传进度(只能通过 response.body.getReader() 监听下载进度)。要实现上传进度条,底层必须依赖 XMLHttpRequest 的 upload.onprogress 事件,这也是我们选用 Axios 的原因。
在前端,我们给 Axios 配置 onUploadProgress 来获取进度。同时,利用现代 JS 的 AbortController 来实现“取消上传”功能

<script setup lang="ts">importaxiosfrom'axios'import{ref}from'vue'constselectedFile=ref<File|null>(null)constmessage=ref('')constprogress=ref(0)// 定义中断控制器letabortController:AbortController|null=nullconstuploadFile=async()=>{if(!selectedFile.value)return// 1. 前端基础校验:大小限制 10MBif(selectedFile.value.size>10*1024*1024){message.value='文件不能超过 10MB'return}constformData=newFormData()formData.append('file',selectedFile.value)abortController=newAbortController()try{message.value='正在上传...'constres=awaitaxios.post('http://localhost:3000/upload',formData,{signal:abortController.signal,// 绑定取消信号// 监听上传进度onUploadProgress:(progressEvent)=>{if(progressEvent.total){progress.value=Math.round((progressEvent.loaded*100)/progressEvent.total)}}})message.value=`上传成功:${res.data.filename}`}catch(error:any){// 捕获取消操作的特殊错误if(axios.isCancel(error)){message.value='上传已取消'}else{message.value=error.response?.data?.msg||'上传失败'}}}// 取消上传的触发函数constcancelUpload=()=>{if(abortController)abortController.abort()}</script>

在 Vue 3 中,不要把 File 对象直接放到 reactive 里,这会导致性能问题。使用 ref 并通过 .value 操作即可。

3 后端实现:多文件与拦截器(实现并发和安全防线)

后端我们继续使用 Multer,但这次升级为 upload.array() 以支持多文件,并加上了 limits 和 fileFilter。这一步体现了后端对内存和存储的保护。

constmulter=require("multer");// 配置安全防线:文件过滤器constfileFilter=(req,file,cb)=>{constallowedTypes=["image/jpeg","image/png","application/pdf"];if(allowedTypes.includes(file.mimetype)){cb(null,true);// 放行}else{cb(newError("仅支持 JPG/PNG/PDF 文件"),false);// 拒绝}};constupload=multer({storage:storage,fileFilter:fileFilter,limits:{fileSize:10*1024*1024,// 限制单文件最大 10MBfiles:5// 限制单次请求最多 5 个文件}});// 使用 upload.array 接收多文件,字段名为 "files"app.post("/upload",upload.array("files",5),(req,res)=>{res.json({msg:"上传成功",files:req.files.map(f=>f.filename)// 返回所有文件的名字});});
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 20:52:34

数据结构01——时间复杂度和空间复杂度

一.什么是数据结构数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在⼀种或多种特定关系的数据集合。不存在一种通用的数据结构针对于所有应用场景&#xff0c;所以产生了多种多样的数据结构来适配不同的环境&#xff1a;例如顺序表、链表、堆栈…

作者头像 李华
网站建设 2026/5/19 3:05:19

彼得林奇的“反向投资“成功案例

彼得林奇的“反向投资”成功案例 关键词&#xff1a;彼得林奇、反向投资、成功案例、投资策略、股票分析 摘要&#xff1a;本文聚焦于彼得林奇的“反向投资”策略及其成功案例。首先介绍了彼得林奇及其反向投资策略的背景&#xff0c;阐述了相关核心概念和联系。接着详细讲解了…

作者头像 李华
网站建设 2026/5/9 14:20:22

企业AI开发与技术实践白皮书2025|附36页PDF文件下载

白皮书探讨了在GenAI时代&#xff0c;企业如何利用大模型技术实现智能化转型。白皮书指出&#xff0c;大模型能力的不断提升为企业带来了无限想象力&#xff0c;但也面临着战略规划、数据治理、算力资源、场景适配等方面的挑战。企业需要构建覆盖顶层设计、技术选型、数据治理、…

作者头像 李华
网站建设 2026/5/11 3:32:44

【Java 新手必看】比较运算符:从概念到实战,附可运行代码案例

比较运算符是 Java 中用于判断 “两个值 / 变量关系” 的核心运算符&#xff0c;也是实现程序逻辑判断&#xff08;如 if/else&#xff09;的基础。新手常混淆 “等于” 和 “赋值”、“等于” 和 “对象相等”&#xff0c;这篇笔记结合可直接运行的代码案例&#xff0c;从基础…

作者头像 李华