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)// 返回所有文件的名字});});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1215813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大厂迷思:为什么顶级工程师会产出难以维护的代码

当你终于通过几轮严苛的技术面试&#xff0c;加入一家享有盛誉的大型科技公司时&#xff0c;往往会对即将接触的代码库抱有极高的期待。你想象着整洁的架构、清晰的文档以及如教科书般完美的逻辑实现。然而现实往往极具冲击力&#xff1a;你所看到的可能是一个由无数补丁堆叠、…

menset的使用方法

menset的使用方法#include <cstring> // 必须包含这个头文件&#xff01; memset(目标内存地址, 填充值, 填充的字节数);填充值只能是「单字节值」memset是按字节填充&#xff0c;所以&#xff1a;✅ 填充0&#xff1a;完全没问题&#xff08;所有类型数组清空都能用&am…

“AUTOSAR?我连CAN都看不懂…” 一个汽车电子工程师的坦白与指南

我刚入职现时&#xff0c;导师指着电脑上复杂的网络拓扑图说&#xff1a;“这个ECU的AUTOSAR架构需要优化。” 我表面点头&#xff0c;手心却在冒汗——获取车软嵌入式&#xff0c;欢迎可&#xff1a;AutoButo。那些分层框图像天书&#xff0c;MCAL、BSW、RTE这些缩写&#xff…

大数据领域数据中台的安全审计与合规

大数据领域数据中台的安全审计与合规 关键词:大数据、数据中台、安全审计、合规、数据安全 摘要:本文聚焦于大数据领域数据中台的安全审计与合规问题。随着大数据技术的迅猛发展,数据中台成为企业整合和管理数据的重要平台。然而,其安全与合规性面临诸多挑战。文章首先介绍…

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

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

Java中strip与trim()的区别

TOC Java中strip与trim()的区别 jdk11及以上版本&#xff0c;java的String支持strip()方法&#xff0c;那么原来的删除空白trim()与strip()的区别时什么&#xff1f; 区别 trim()&#xff1a;仅处理字符串首尾的ASCII空白字符串&#xff08;小于等于\u0020字符&#xff0c;…

Python入门——字符串

Python快速入门&#xff08;1&#xff09;——字符串字符串索引访问常用倒序访问截取/切片常用方法长度判空大小写删除空白分割最近需要使用到python&#xff0c;本系列适合有其他编程语言&#xff08;C/C/Java&#xff09;基础的同学&#xff0c;帮助大家一起快速上手Python&a…

多级缓存必要性

Java多级缓存设计&#xff1a;应对微博明星官宣的高并发场景 一、多级缓存原理与必要性 1.1 为什么需要多级缓存&#xff1f; 单级缓存的问题&#xff1a; 性能瓶颈&#xff1a;所有请求都打到同一缓存层&#xff0c;压力集中容错性差&#xff1a;缓存层故障直接影响整体可…

OpenHarmony Flutter 分布式安全防护:跨设备身份认证与数据加密传输方案 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

tp3.2性能暂时优化调整

// 1. 禁用TP3.2的冗余组件(在入口文件index.php最顶部添加)define(APP_DEBUG, false); // 关闭调试模式(必须)define(BIND_MODULE,Api); // 绑定模块,减少模块扫描define(THINK_PATH, __DIR__./ThinkPHP/);// 禁…

百万数据报表操作 - 努力-

百万数据报表操作百万数据报表操作,Excel报表一、百万数据报表概述 1.1 百万数据报表概述 我们都知道Excel可以分为早期的Excel2003版本(使用POI的HSSF对象操作)和Excel2007版本(使用POI的XSSF操作),两者对百万数…

电商系统-下单功能 - 努力-

电商系统-下单功能电商系统-下单功能,SpringCloud一、 订单结算页 本文介绍:订单结算页,用户地址列表,支付方式选择,用户商品清单,生成订单 ,分布式ID,库存扣减,增加用户积分业务功能。 1.1 订单结算页 用户收货…

软件测试—即时通讯测试方法

一、即时通讯实现方式 1.短轮询&#xff08;Short Polling&#xff09; 短轮询是一种客户端定期向服务器发送HTTP请求以检查是否有新数据的简单技术。无论服务器是否有新数据&#xff0c;客户端都会在固定的时间间隔后再次请求。 实现机制 客户端向服务器发送HTTP请求&#xff…

告别if-else噩梦:流程编排技术

作为一个优秀的程序员&#xff0c;要守住职业的底线。能简单快速的完成的一件事&#xff0c;就一定要用简单的方案快速完成。不可过度的设计&#xff0c;始终保持系统的简洁&#xff01; 曾几何时&#xff0c;我对于流程编排这件事 嗤之以鼻&#xff0c;为什么呢&#xff1f;我…

attn_scores注意力分计算-记录

querys 是 2*6*2&#xff0c;keys也是2*6*2 attn_scores querys keys.transpose(1,2)attn_scores 最终维度是 266&#xff1b;数值上是两个矩阵的批量矩阵乘法结果&#xff0c;每个样本对应一个 66 的注意力分数矩阵 transpose(1,2) 交换 keys 的第 1 维和第 2 维&#xff1…

多头注意力中的张量重塑

view PyTorch 的view() 是张量「重塑&#xff08;Reshape&#xff09;」函数&#xff0c;用于改变张量的维度形状但不改变数据本身 在多头注意力中&#xff0c;view()的核心作用是将总隐藏维度拆分为「注意力头数 单头维度」&#xff0c;实现多头并行计算 核心规则 tensor.vie…

第二周作业wp

第二周作业wp [SWPUCTF 2021 新生赛]easyupload3.0 题目提示已经很明显了&#xff0c;我们要提交一个.jpg的文件。那么我们就把一个木马文件做成jpg文件。 这里我们把文件成功上传&#xff0c;然后通过蚁剑连接 连接之后&#xff0c;寻找flag。 如图&#xff0c;成功找到。 2…

吐血推荐专科生必用TOP9AI论文网站

吐血推荐专科生必用TOP9AI论文网站 2026年专科生论文写作工具测评&#xff1a;为何需要一份精准榜单&#xff1f; 随着AI技术在教育领域的深入应用&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上五花八门的论文辅助平台&#xff0c;…

Python 调用大模型(LLM) - 努力-

Python 调用大模型(LLM)Python 调用大模型(LLM),提示词工程一、提示词工程 提示词(Prompt):是引导大模型(LLM)进行内容生成的命令(一句话、一个问题等)。 提示词工程(Prompt Enginnering):通过有技巧的编写提示…

Python核心语法-Python自定义模块、Python包 - 努力-

Python核心语法-Python自定义模块、Python包Python核心语法,Python自定义模块、Python包一、python 模块 Python模块(module):一个Python文件(.py)就是一个模块,模块是Python程序的基本组织单位。在模块中可以定义…