首页 > 其他分享 >大文件分块上传实现

大文件分块上传实现

时间:2023-02-07 17:37:22浏览次数:25  
标签:文件 const 分块 ctx 上传 size

原理说明

对于大文件上传这个问题,作为一个有追求的程序员一定会有所思考,解决这个问题无非就是将文件变小,也就是通过对文件压缩或者对大文件分块后再上传。下面我们就来看看将文件资源分块的方案

代码实现之前端代码

(1)创建一个vue项目

(2)写一个简单页面

<input type="file" @change="getFile" name="" value="" />

(3)获取上传文件

async getFile(e) {

// 1.获取文件

let file = e.target.files;

this.currFile = file[0];

},

(4)大文件分块

// 获取文件分块
getFileChunk(file, chunkSize) {
let that = this;
return new Promise((resovle) => {
let blobSlice =
File.prototype.slice ||
File.prototype.mozSlice ||
File.prototype.webkitSlice,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();

    //使用fileReader将文件块转为文件流,方便生成文件hash值
    //这里生成文件hash的作用
    fileReader.onload = function (e) {
      const chunk = e.target.result;
      spark.append(chunk);
      currentChunk++;
      if (currentChunk < chunks) {
        loadNext();
      } else {
        let fileHash = spark.end();
        resovle({ fileHash });
      }
    };

    fileReader.onerror = function () {
      console.warn("oops, something went wrong.");
    };

    function loadNext() {
      //文件切块
      let start = currentChunk * chunkSize,
      end =start + chunkSize >= file.size ? file.size : start + chunkSize;
      let chunk = blobSlice.call(file, start, end);
      that.fileChunkList.push({
        chunk,
        size: chunk.size,
        name: that.currFile.name,
        percentage:0
      });
      fileReader.readAsArrayBuffer(chunk);
    }

    loadNext();
  });
},

(5)上传分块和合并请求

代码实现之后端代码

(1)初始化node.js项目,提供上传接口和合并接口

npm install -g koa-generator

koa2 项目名

npm install

router.post("/upload", async (ctx) => {
ctx.set("Content-Type", "application/json");
ctx.body = JSON.stringify({ data: { code: 2000, }, message: "successful!", });
});

router.post("/mergeChunk", async (ctx) => {
ctx.set("Content-Type", "application/json");
ctx.body = JSON.stringify({ data: { code: 2000, }, message: "successful!", });
});

可能有跨域:需要配置一下

const cors = require('koa2-cors');

(2)使用koa-body处理文件分块

const koaBody = require("koa-body")

// 上传请求
    uploadChunks(fileHash) {
      let that = this;
      const requests = this.fileChunkList.map((item, index) => {
        const formData = new FormData();
        formData.append(
          `${this.currFile.name}-${fileHash}-${index}`,
          item.chunk
        );
        // 上传
        return uploadFile("/upload", formData, that.onUploadProgress(item));
      });
      Promise.all(requests).then(() => {
        // 合并
        mergeChunks("/mergeChunks", {
          size: that.DefualtChunkSize,
          filename: that.currFile.name,
        });
      });
    },
      
      
      
import axios from "axios";
 
const baseURL = 'http://localhost:3001';
 
export const uploadFile = (url, formData, onUploadProgress = () => { }) => {  
    return axios({  
    method: 'post',  
    url,  
    baseURL,   
    headers: {   
      'Content-Type': 'multipart/form-data'   
    },  
    data: formData,   
    onUploadProgress 
  });
}
 
export const mergeChunks = (url, data) => { 
  return axios({  
    method: 'post',  
    url,    
    baseURL,   
    headers: { 
      'Content-Type': 'application/json'  
    },  
    data 
  });
}
(3)处理合并请求

// 合并请求
router.post("/mergeChunks", async (ctx) => {
  const { filename, size } = ctx.request.body;
  // 合并 chunks
  await mergeFileChunk(filename, size);
 
  // 处理响应
  ctx.set("Content-Type", "application/json");
  ctx.body = JSON.stringify({
    data: {
      code: 2000,
      filename,
      size,
    },
    message: "merge chunks successful!",
  });
});



 

(4)优化文件小块的进度条



 注意:这里在切块的时候,需要给每一块加上percentage字段,这样才能响应化!!!

标签:文件,const,分块,ctx,上传,size
From: https://www.cnblogs.com/coderwhytop/p/17099197.html

相关文章

  • 使用ajaxSubmit上传文件总结
    一、使用步骤①引入文件<scripttype="text/javascript"src="js/jquery-1.11.3.min.js"></script><scripttype="text/javascript"src="js/jquery.form.js"></scrip......
  • Java下载文件的4种方式总结
    1.以流的方式下载.publicHttpServletResponsedownload(Stringpath,HttpServletResponseresponse){try{//path是指欲下载的文件的路径。Filefile=newF......
  • fetch上传
    //导出我点评的exportMyComment(){letdata={"pageNo":this.commentParams.pageNo,"pageSize":this.myCommentParams.pageSize,"param":this.myComment......
  • 原生文件上传
    <inputid="uplode"ref="imgFile"accept=".jpeg,.png,.gif,.jpg"hiddenmultiple="multiple"type="file"@change="uploadFile($event)"/><!--......
  • .eslintrc.js文件内容/配置eslint/eslint参数
    首先放一个官网的链接​​​​​​Listofavailablerules-ESLint中文文档然后直接上代码这里以vue项目为例,主要两个文件,1是.eslintrc.js文件(配置),2是.eslintignore(忽......
  • vue项目 前端js实现根据文件url批量压缩下载成zip包
    1.npminstalljszip--save/yarnaddjszip-S2.npminstallfile-saver--save/yarnaddfile-saver-S3.yarnaddaxios以下为完整代码 <template>......
  • PHPMyWind支持PowerPoint上传
    ​ 图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.j......
  • 微信小程序导入项目:报错 [app.json文件内容错误]app.json未找到 解决
    打开微信小程序控制台报错:原因:找不到入口中的文件。第一级文件目录里确实找不到app.json文件,但是打开二级目录可以看到app.json解决方法:1、在project.config.json文件......
  • 如何在 C# 项目中链接一个文件夹下的所有文件
    在C#项目中通过链接方式引入文件可以让我们在项目中使用这些文件中的代码。常见的比如链接AssemblyInfo.cs文件,这样我们就可以在项目中使用这个文件中的版本号等信息......
  • CAD怎么导入系统设置文件?浩辰CAD系统设置文件导入步骤
    很多设计师小伙伴换电脑后重新安装了浩辰CAD软件,但是想要将给之前的CAD系统设置文件导入到新电脑的浩辰CAD软件中,这种情况该怎么办呢?本节教程小编就来给大家分享一下浩辰CA......