全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2025-05-14_你还不知道的大文件上传

您的位置:首页 >> 新闻 >> 行业资讯

你还不知道的大文件上传 点击关注公众号,“技术干货” 及时达!说起文件上传,在我们的开发中是绕不过去的话题。但要是碰到几十 MB 甚至 GB 级别的大文件,传统上传方式就有点 “拉胯” 了。今天就给大伙唠唠前端大文件上传,讲讲它的原理、能解决啥问题、有哪些关键功能,再给大家推荐一个超实用的大文件上传库,让大文件上传不再是难题。 一、大文件上传是啥?(一)大文件上传的定义简单来说,大文件上传就是把个头很大的文件,从咱们的客户端,像浏览器啥的,传到服务器上。这些大文件要是用传统上传方法,很容易出现上传失败、网络超时,还可能把服务器资源占得死死的。所以,大文件上传一般得靠分片上传、断点续传、并行上传这些技术,才能顺顺利利完成。 (二)大文件上传解决的问题「网络不稳定」:网络这东西,时好时坏。大文件上传的时候,网络要是波动或者断了,很容易就上传失败。大文件上传技术就能应对这种情况,保证上传能完成。「服务器资源限制」:大文件上传要是处理不好,服务器的内存和 CPU 就遭老罪了,搞不好服务器都得崩溃。用对技术,就能减少对服务器资源的占用,让服务器稳稳地运行。「用户体验」:有了上传进度展示、断点续传这些功能,用户能随时知道上传到啥程度了,就算上传中断,也不用从头再来,体验感直接拉满。「文件完整性验证」:文件传输的时候,数据有可能损坏或者丢失。大文件上传技术有文件完整性验证,能保证上传的文件和原来的一模一样。(三)大文件上传对比普通文件上传的优势「能处理大文件」:普通文件上传碰到 GB 级别的大文件,基本就歇菜了。大文件上传用分片技术,再大的文件都能搞定。「断点续传」:普通文件上传中断了就得重新开始,大文件上传能接着没传完的地方继续,省时间又省带宽。「并行上传」:大文件上传可以把文件分成好多片同时上传,速度 “蹭蹭” 往上涨。「优化资源利用」:分片上传后,服务器每次处理的文件片段小,内存占用就少,服务器性能也能提升。「精准进度监控」:大文件上传能更准确地显示上传进度,用户心里有数。二、前端实现大文件上传的关键要点从前端角度看,要实现大文件上传,得搞定下面这些关键功能: (一)文件分片把大文件按照固定大小,比如 1MB 或者 5MB,切成一个个小文件,也就是分片。这可以用 File API 里的 File.slice () 方法来实现。 (二)分片上传用 XMLHttpRequest 或者 Fetch API,把每个分片一个一个传到服务器。为了更快,还能同时上传好几个分片,也就是并行上传。 (三)断点续传上传要是中断了,前端得记住哪些分片已经传了。下次接着传没传完的。这得前端和服务器一起配合,服务器一般会记录已经上传的分片信息,像文件哈希值或者分片索引。 (四)上传进度监控通过 XMLHttpRequest 的 progress 事件,或者 Fetch API 的 ReadableStream,实时监控上传进度。然后算出已经上传的百分比,展示给用户。 (五)文件完整性校验文件上传完了,前端算一下文件的哈希值,比如 MD5 或者 SHA-256,再和服务器那边校验一下,保证文件没出问题。这得用 FileReader 读取文件内容来生成哈希值。 (六)错误处理与重试机制上传的时候难免会遇到网络错误、服务器错误啥的。前端得有一套完善的错误处理机制,每个分片还要有重试机制,保证上传失败的分片能重新传。 (七)并发控制要控制好同时上传的分片数量,不然太多请求会占满带宽,服务器也扛不住。可以用队列或者 Promise 池来管理并发上传任务。 (八)用户体验优化得给用户一个清晰直观的界面反馈,像进度条、上传速度、剩余时间这些都得展示出来。另外,还要支持拖拽上传、文件选择、批量上传这些实用功能。 (九)安全性考虑为了防止有人上传恶意文件,得校验文件类型,限制文件大小。要是有敏感数据,就用 HTTPS 这些加密方式传输。 三、宝藏大文件上传库 ——enlarge - file - upload自己从头写一个大文件上传库,难度可不小,要实现这么多功能,短时间内根本搞不定。给大家推荐一个超好用的库,叫 enlarge - file - upload。上面说的这些功能,它都实现了,不管你用 vue2、vue3、react,还是 jquery 原生 js 开发项目,都能直接用,真正做到开箱即用。 下面讲讲它在不同环境里咋用: (一)安装npm install enlarge-file-upload 安装很简单,就按常规的 npm 安装方式就行。在项目目录下打开命令行,输入npm install enlarge-file-upload,等安装完,就能在项目里用这个库了。具体安装命令也可以去 npm 官网瞅瞅:https://www.npmjs.com/package/enlarge-file-upload (二)参数介绍这个库的参数挺多,能满足各种项目需求。详细的参数说明可以看官方文档。这里给大家讲讲常用的几个参数: file:这个是要上传的文件对象,必须得有。你选好要上传的文件,获取到的文件对象就填这儿。serverUrl:这是服务器接收文件上传的接口地址,得填对,不然文件传不到服务器上。onProgress:这是个回调函数,用来监听上传进度。上传的时候,它会实时被触发,通过它能拿到当前的上传进度百分比,方便展示给用户看。onSuccess:文件上传成功了,就会执行这个回调函数。你可以在里面给用户提示上传成功,或者更新一下页面状态啥的。onError:要是上传出错了,这个回调函数就会被调用,它会带着错误信息,方便你排查问题。(三)使用案例「jquery 原生 js 中使用示例」!DOCTYPEhtml htmllang="en" head metacharset="UTF-8"/ metaname="viewport"content="width=device-width, initial-scale=1.0"/ title文件上传/title /head scriptsrc="https://cdn.jsdelivr.net/npm/enlarge-file-upload/dist/upload.min.js"/script !-- 引入 Axios 库,用于发送 HTTP 请求 -- scriptsrc="https://cdn.jsdelivr.net/npm/axios"/script body inputtype="file"id="fileInput"/ buttonid="pauseButton"暂停上传/button buttonid="resumeButton"继续上传/button divid="progress"上传进度:0%/div divid="speed"上传速度:0 MB/s/div script // 定义上传函数 asyncfunctionuploadFunction({ chunk, index, hash, cancelToken }){ constformData =newFormData(); formData.append("chunk", chunk); formData.append("hash", hash); formData.append("index", index); awaitaxios.post("http://localhost:3000/api/users", formData, { cancelToken, } // 使用示例 constconfig = { chunkSize:5*1024*1024,// 5MB concurrency:5, maxRetries:3, // startOffset: 6, // 从索引为10的切片位置开始传 // includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效 uploadFunction, onProgress:(progress) ={ document.getElementById( "progress" ).innerText =`上传进度:${state.progress.toFixed(2)}%`; }, onSuccess:()={ console.log("上传完毕"); }, onSpeed:(speed) ={ document.getElementById("speed").innerText =`上传速度:${speed}`; }, const{ upload, pause, resume, state } = createUploader(config); constfileInput =document.getElementById("fileInput"); fileInput.addEventListener("change", () = { constfile = fileInput.files[0]; upload(file); // 暂停上传 document.getElementById("pauseButton").addEventListener("click", () = { pause(); // 继续上传 document.getElementById("resumeButton").addEventListener("click", () = { resume(); /script /body /html /html 在这个例子里,先引入了jquery库和enlarge-file-upload库。页面加载完后,给上传按钮绑定了点击事件。点按钮的时候,就去获取文件输入框里选的文件。要是有文件,就创建EnlargeFileUpload实例,把文件对象、服务器上传接口地址,还有各种回调函数传进去,最后调用start方法开始上传文件。 「在 vue3 中使用」template div inputtype="file"@change="handleFileChange" button@click="uploadFile"上传文件/button /div /template scriptsetup importEnlargeFileUploadfrom'enlarge-file-upload'; constfileRef = ref(null); consthandleFileChange =(e) ={ fileRef.value = e.target.files[0]; }; constuploadFile =()={ if(fileRef.value) { constuploader =newEnlargeFileUpload({ file: fileRef.value, serverUrl:'http://your-server-url.com/upload', onProgress:(progress) ={ console.log(`上传进度:${progress}%`); }, onSuccess:()={ console.log('文件上传成功'); }, onError:(error) ={ console.error('文件上传失败', error); } uploader.start(); } }; /script 在 vue3 项目里,用ref定义了一个fileRef来存选的文件。文件选择框内容变了,handleFileChange函数就把选的文件赋值给fileRef。点上传按钮的时候,看看fileRef有没有值,有值就创建EnlargeFileUpload实例开始上传文件,还设置了上传进度、成功和失败的回调函数。 「在 vue2 中使用」template div inputtype="file"@change="handleFileChange"/ button@click="handlePause"暂停上传/button button@click="handleResume"继续上传/button div上传进度:{{ progress.toFixed(2) }}%/div div上传速度:{{ speed }}/div /div /template script importVuefrom"vue"; importcreateUploaderfrom"enlarge-file-upload"; importaxiosfrom"axios"; exportdefaultVue.extend({ data() { return{ progress:0,// 进度 speed:"0 MB/s",// 速度 uploader:null,// 上传器实例 }, methods: { // 定义上传函数 asyncuploadFunction({ chunk, index, hash, cancelToken }) { constformData =newFormData(); formData.append("chunk", chunk); formData.append("hash", hash); formData.append("index", index.toString()); awaitaxios.post("http://localhost:3000/api/users", formData, { cancelToken, }, // 文件选择处理 handleFileChange(event) { constfile = event.target.files?.[0]; if(file this.uploader) { this.uploader.upload(file); } }, // 暂停上传 handlePause() { if(this.uploader) { this.uploader.pause(); } }, // 继续上传 handleResume() { if(this.uploader) { this.uploader.resume(); } }, }, created() { constuploaderConfig = { chunkSize:5*1024*1024,// 5MB concurrency:5, maxRetries:3, uploadFunction:this.uploadFunction, onProgress:(progressValue) ={ this.progress = progressValue; }, onSuccess:()={ console.log("上传完毕"); }, onSpeed:(speedValue) ={ this.speed = speedValue; }, // 创建上传器实例 this.uploader = createUploader(uploaderConfig); }, }); /script stylescoped/style vue2 项目里,在data里定义了file变量存文件。handleFileChange方法获取选的文件,点上传按钮的时候,要是file有值,就创建EnlargeFileUpload实例上传文件,设置好回调函数处理上传过程里的各种情况。 「React 中使用示例」importReact, { useRef, useMemo }from'react'; importEnlargeFileUploadfrom'enlarge-file-upload'; constFileUploadComponent =()={ constfileInputRef = useRef(null); constuploadFile =()={ constfile = fileInputRef.current.files[0]; if(file) { constuploader = useMemo(()=newEnlargeFileUpload({ file: file, serverUrl:'http://your-server-url.com/upload', onProgress:(progress) ={ console.log(`上传进度:${progress}%`); }, onSuccess:()={ console.log('文件上传成功'); }, onError:(error) ={ console.error('文件上传失败', error); } }), [file]); uploader.start(); } return( div inputtype="file"ref={fileInputRef}/ buttononClick={uploadFile}上传文件/button /div }; exportdefaultFileUploadComponent; React 项目里,用useRef创建了fileInputRef来引用文件输入框。点上传按钮的时候,从fileInputRef里拿选的文件。为了防止组件重新渲染的时候重复创建EnlargeFileUpload实例,用useMemo来创建上传实例,设置好回调函数。最后在页面里渲染文件输入框和上传按钮。 「封装为 react Hooks」importReact, { useState, useMemo }from"react"; importcreateUploaderfrom"enlarge-file-upload"; importtype { Config, UploadOptions }from"enlarge-file-upload"; importaxiosfrom"axios"; constFileUpload =()={ const[progress, setProgress] = useState(0); const[speed, setSpeed] = useState("0 MB/s"); // 定义上传函数 asyncfunctionuploadFunction({ chunk, index, hash, cancelToken, }: UploadOptions){ constformData =newFormData(); formData.append("chunk", chunk); formData.append("hash", hash); formData.append("index", index); awaitaxios.post("http://localhost:3000/api/users", formData, { cancelToken, } constuploaderConfig: Config = useMemo( ()=({ chunkSize:5*1024*1024,// 5MB concurrency:5, maxRetries:3, // startOffset: 6, // 从索引为10的切片位置开始传 // includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效 uploadFunction, onProgress:(progress) ={ setProgress(progress); }, onSuccess:()={ console.log("上传完毕"); }, onSpeed:(speed) ={ setSpeed(speed); }, }), [] constuploader = useMemo( ()=createUploader(uploaderConfig), [uploaderConfig] consthandleFileChange =(event) ={ constfile = event.target.files[0]; uploader?.upload(file); consthandlePause =()={ uploader?.pause(); consthandleResume =()={ uploader?.resume(); return( div inputtype="file"onChange={handleFileChange}/ buttononClick={handlePause}暂停上传/button buttononClick={handleResume}继续上传/button div上传进度:{progress.toFixed(2)}%/div div上传速度:{speed}/div /div }; exportdefaultFileUpload; 这段代码把文件上传功能封装成了 React Hook。Hook 里用useRef创建文件输入框的引用,uploadFile函数处理文件上传逻辑,最后返回fileInputRef和uploadFile,方便在其他组件里复用文件上传功能。 「使用上面封装好的 Hooks 示例」import{ useState, useMemo, useCallback }from"react"; importcreateUploaderfrom"enlarge-file-upload"; importtype { Config, UploadOptions }from"enlarge-file-upload"; importaxiosfrom"axios"; constuseFileUploader =()={ const[progress, setProgress] = useState(0); const[speed, setSpeed] = useState("0 MB/s"); constuploadFunction = useCallback( async({ chunk, index, hash, cancelToken }: UploadOptions) = { constformData =newFormData(); formData.append("chunk", chunk); formData.append("hash", hash); formData.append("index", index); awaitaxios.post("http://localhost:3000/api/users", formData, { cancelToken, }, [] constuploaderConfig: Config = useMemo( ()=({ chunkSize:5*1024*1024,// 5MB concurrency:5, maxRetries:3, // startOffset: 6, // 从索引为10的切片位置开始传 // includeChunks:[1,6], // 只上传索引为1和6的切片,只有startOffset为0或空时才生效 uploadFunction, onProgress:(progress) ={ setProgress(progress); }, onSuccess:()={ console.log("Upload complete"); }, onSpeed:(speed) ={ setSpeed(speed); }, }), [uploadFunction] constuploader = useMemo( ()=createUploader(uploaderConfig), [uploaderConfig] constuploadFile = useCallback( (file) ={ uploader?.upload(file); }, [uploader] constpauseUpload = useCallback(()={ uploader?.pause(); }, [uploader]); constresumeUpload = useCallback(()={ uploader?.resume(); }, [uploader]); return{ progress, speed, uploadFile, pauseUpload, resumeUpload, }; exportdefaultuseFileUploader; 这个示例里,引入封装好的useFileUploadHook,通过解构拿到fileInputRef和uploadFile。在组件里用fileInputRef关联文件输入框,点按钮就调用uploadFile函数上传文件,在 React 项目里用起来就更方便了。 大文件上传在前端开发里很重要,搞懂原理和实现方法,再用好工具,就能给用户更好的上传体验。希望这篇文章能帮大家深入了解前端大文件上传,在项目开发里用得得心应手。 关注更多AI编程资讯请去AI Coding专区:https://juejin.cn/aicoding 点击"阅读原文"了解详情~ 阅读原文

上一篇:2024-06-05_5月案例:B站反讽喜剧、大润发母亲节文案 下一篇:2025-09-10_尼康发布与RED联袂打造的全画幅“Z CINEMA”系列微单相机ZR

TAG标签:

17
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价