0


文件分块+断点续传 实现大文件上传全栈解决方案(前端+nodejs)

1. 文件分块

将大文件切分成较小的片段(通常称为分片或块),然后逐个上传这些分片。这种方法可以提高上传的稳定性,因为如果某个分片上传失败,只需要重新上传该分片而不需要重新上传整个文件。同时,分片上传还可以利用多个网络连接并行上传多个分片,提高上传速度。

2. 断点续传

在上传过程中,如果网络中断或上传被中止,断点续传技术可以记录已成功上传的分片信息,以便在恢复上传时继续上传未完成的部分,而不需要重新上传整个文件。这种技术可以大大减少上传失败的影响,并节省时间和带宽。

3. node项目目录初始化

在这里插入图片描述

  1. 安装依赖- express 敏捷启动服务- multer 读取文件,存储- cors 解决跨域
  2. 目录结构- src - TED.mp4 (长视频,10分钟,可以下载这个 https://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4)- uploads 存放切片- video 存放将切片拼接后的视频- index.html 前端页面

代码附上

index.html

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><title>Document</title></head><body><inputid="file"type="file"/><script>// functions// 实现切片的方法constmakeChunk=(file, size =1024*1024*4)=>{const chunks =[];for(let i =0; i < file.size; i += size){const chunk = file.slice(i, i + size);
          chunks.push(chunk);}return chunks;};// 上传分片后的文件方法constuploadChunks=(chunks)=>{// 1. 使用Promise.all保证所有上传方法执行成功// 2. 必须要给每个分片文件加标识,才可以让node端进行按序拼接const list =[];for(let i =0; i < chunks.length; i++){const formData =newFormData();
          formData.append("filename","ted");
          formData.append("index", i);
          formData.append("chunk", chunks[i]);// 千万注意,切片文件要最后append否则会出现意外的bug

          list.push(fetch("http://localhost:3000/upload",{method:"POST",body: formData,}));}

        Promise.all(list).then((res)=>{
            console.log("上传成功", res);fetch("http://localhost:3000/merge",{method:"POST",headers:{"Content-Type":"application/json",},body:JSON.stringify({fileName:"TED演讲10分钟长视频",}),});}).catch((err)=>{
            console.error("上传失败", err);});};// logicconst file = document.querySelector("#file");
      file.addEventListener("change",(e)=>{let file = e.target.files[0];// 我们只处理单个文件因此取第一个元素即可// file是一个对象,底层继承于Blob,借助于Blob身上的slice方法,可以实现对大文件的分片操作
        console.log(file);const chunks =makeChunk(file);
        console.log("chunks:", chunks);uploadChunks(chunks);});</script></body></html>

index.js

import fs from"node:fs";import path from"node:path";import express from"express";import multer from"multer";import cors from"cors";

console.log("cors:", cors);// 1. 初始化multerconst storage = multer.diskStorage({// 指定切片存放目录destination:function(req, file, cb){cb(null,"../uploads/");},filename:function(req, file, cb){
    console.log("req.body.index:", req.body.index);
    console.log("file", file);cb(null,`${req.body.filename}-${req.body.index}`);},});const upload =multer({ storage });const app =express();
app.use(cors());
app.use(express.json());// upload.single("chunk") 其中chunk对应前端上传的文件切片名字
app.post("/upload", upload.single("chunk"),(req, res)=>{
  console.log("req.body:", req.body);
  res.header("Content-Type","application/json;charset=utf-8");
  res.send("ok");});// 拼接切片
app.post("/merge",(req, res)=>{// 获取uploadDir的目录const uploadDir = path.join(process.cwd(),"../uploads");const dirs = fs.readdirSync(uploadDir);// 发现是乱序的// 对dirs数组进行排序
  dirs.sort((a, b)=>{return a.split("-")[1]- b.split("-")[1];});const videoDir = path.join(
    process.cwd(),"../video",`${req.body.fileName}.mp4`);

  dirs.forEach((item)=>{// 合并成一个完整的文件至video目录
    fs.appendFileSync(videoDir, fs.readFileSync(path.join(uploadDir, item)));// 删除已合并的切片文件
    fs.unlinkSync(path.join(uploadDir, item));});
  console.log(dirs);
  res.send("okk");});

app.listen(3000,()=>{
  console.log("server is running at port 3000");});

最终效果

在这里插入图片描述
在这里插入图片描述

标签: 前端 node.js

本文转载自: https://blog.csdn.net/weixin_51431277/article/details/138304833
版权归原作者 WongLeer 所有, 如有侵权,请联系我们删除。

“文件分块+断点续传 实现大文件上传全栈解决方案(前端+nodejs)”的评论:

还没有评论