工作中如何实现大文件的上传?

问题背景

在 Web 开发中,上传大文件是一个常见的需求。然而,由于 HTTP 协议的限制和网络环境的不稳定性,直接将大文件一次性上传到服务器可能会导致性能问题或者上传失败。因此,需要采用一些特殊的技术和策略来实现高效的大文件上传。

解决方案

一种常用的解决方案是将大文件分片(Chunk)上传。即将大文件拆分为多个较小的块,然后逐个上传这些块。在服务器端,接收到这些块后再进行合并,最终得到完整的文件。

前置知识

在实现大文件上传之前,你需要了解以下几个概念和技术:

文件分片: 将大文件分割成多个较小的块(chunk),每个块的大小通常在几百 KB 到几 MB 之间。

文件元数据: 除了文件内容,还需要传输文件的元数据,如文件名、文件类型等。

文件上传进度: 为了提供更好的用户体验,应该能够实时显示上传进度。

服务器端处理: 服务器需要接收和处理每个分片,并在所有分片上传完毕后进行合并操作。

代码示例

以下是一个使用 JavaScript 和 Node.js 实现大文件分片上传的示例:

前端代码(使用 Axios 发送分片请求)

js 复制代码
const CHUNK_SIZE = 5 * 1024 * 1024; // 每个分片的大小(这里设置为5MB)  
  
async function uploadFile(file) {  
  const totalChunks = Math.ceil(file.size / CHUNK_SIZE);  
    
  for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {  
    const start = chunkIndex * CHUNK_SIZE;  
    const end = Math.min(start + CHUNK_SIZE, file.size);  
    const chunk = file.slice(start, end);  
      
    const formData = new FormData();  
    formData.append('file', chunk);  
    formData.append('chunkIndex', chunkIndex);  
    formData.append('totalChunks', totalChunks);  
      
    await axios.post('/upload', formData, {  
      headers: {  
        'Content-Type': 'multipart/form-data'  
      },  
      onUploadProgress: progressEvent => {  
        const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);  
        console.log(`Chunk ${chunkIndex + 1}/${totalChunks} uploaded: ${progress}%`);  
      }  
    });  
  }  
}

后端代码(使用 Express 处理分片上传)

js 复制代码
// 后端代码(使用 Express 处理分片上传)  
  
const fs = require('fs');  
const path = require('path');  
const express = require('express');  
const multer = require('multer');  
  
const app = express();  
const upload = multer({ dest: 'uploads/' });  
  
app.post('/upload', upload.single('file'), (req, res) => {  
  const { file, body: { chunkIndex, totalChunks } } = req;  
  const filePath = path.join('uploads/', file.originalname + '-' + chunkIndex);  
    
  fs.renameSync(file.path, filePath);  
    
  if (parseInt(chunkIndex, 10) === parseInt(totalChunks, 10) - 1) {  
    // 最后一个分片上传完成,进行合并操作  
    const writeStream = fs.createWriteStream(path.join('uploads/', file.originalname));  
      
    for (let i = 0; i < totalChunks; i++) {  
      const chunkPath = path.join('uploads/', file.originalname + '-' + i);  
      const chunk = fs.readFileSync(chunkPath);  
      fs.unlinkSync(chunkPath);  
      writeStream.write(chunk);  
    }  
      
    writeStream.end();  
  }  
    
  res.sendStatus(200);  
});  
  
app.listen(3000, () => {  
  console.log('Server started on port 3000');  
});

在上面的示例中,前端使用 Axios 库发送分片请求,后端使用 Express 框架和 Multer 中间件处理分片上传。前端代码会将大文件切割成多个块并逐个上传,同时显示上传进度。后端在接收到每个分片后,将其保存在服务器上,并在最后一个分片上传完成后进行合并操作。

总结

总的来说,大文件上传的关键是将大文件分片上传,以提高性能和稳定性。这种分片上传的方法适用于各种类型的 Web 应用和文件上传场景,并且可以根据具体需求进行定制和扩展。

希望本文对你有所帮助!如果你有任何问题,请随时私信我。

相关推荐
你别说话了21 分钟前
Vue项目解决跨域
前端·javascript·vue.js
唐青枫1 小时前
http-server:别再双击 index.html,一条命令把目录变成网站
前端·javascript
网安蟹佬霸1 小时前
OSINT开源情报收集实战:从信息搜集到资产测绘(2026最新万字保姆级指南)
前端·网络·安全·web安全·网络安全·开源
单线程_012 小时前
【源码阅读】Vue3 Tokenizer 词法分析器完整状态机流转深度梳理(3.4+ 新版架构)
前端
PBitW2 小时前
PM 丢来 3 个 Excel、12 个功能、4 种情形?用 TRAE Work 30 分钟整理成前端开发文档
前端·trae
风骏时光牛马4 小时前
AIAgent高可用架构:弹性容错与故障自愈的落地实践
前端
IT_陈寒4 小时前
Vue的响应式什么时候会失灵?这个坑我踩了
前端·人工智能·后端
烟锁池塘柳05 小时前
解决 Firefox 浏览器网页文本选中高亮不明显问题(含仅修改特定网站高亮显示的方案)
前端·firefox
Patrick_Wilson5 小时前
Web 认证方案技术指南
前端·后端·面试
YuJie5 小时前
JSBridge 基础知识
前端·javascript