nodejs 切片断点续传

nodejs服务端 body解析用的是 const formidableMiddleware = require("express-formidable");

/**
 * 切片上传
 *
 */
const PATH = require("path");
const FS = require("fs");
const mkDir = require("./ApiMkDir"); // 创建目录的封装方法

module.exports = function (req, res, config) {
  return new Promise((resolve, reject) => {
    // 获取时间
    // 生成储存目录名称
    let date = new Date();
    let path = `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}`;
    // 文件目录
    let savePath = PATH.resolve(config.root, "assets/" + path);
    let cachePath = PATH.resolve(config.root, "cacheUploads");
    // 判断目录是否存在,不存在创建目录
    if (!FS.existsSync(savePath)) mkDir(savePath);
    if (!FS.existsSync(cachePath)) mkDir(cachePath);
    // 获取分片数据
    let { index, total, md5 } = req.fields;
    // 临时文件路径
    let TmpFileName = cachePath + "/" + req.files["file"].name;
    // 存储文件路径
    let FileName = savePath + "/" + req.files["file"].name;
    // 当前文件传输进度管理
    let TmpFileNameMange = cachePath + "/" + req.files["file"].name + ".txt";
    TmpFileName = PATH.normalize(TmpFileName);
    TmpFileNameMange = PATH.normalize(TmpFileNameMange);
    FileName = PATH.normalize(FileName);
    // 是否第一次传输
    if (FS.existsSync(FileName)) FS.unlinkSync(FileName);
    if (FS.existsSync(TmpFileNameMange)) {
      let test = FS.readFileSync(TmpFileNameMange, { encoding: "utf-8" });
      if (test) {
        let { i, md5: md } = JSON.parse(test);
        if (md === md5 && Number(i) > Number(index)) {
          resolve(i);
          return;
        }
      }
    }
    // 获取上传的文件buffer
    let buffer = FS.readFileSync(req.files["file"].path);
    // 写入临时文件
    if (FS.appendFileSync(TmpFileName, buffer)) reject();
    // 传输完成,移动到保存目录
    // 写入保存文件
    FS.writeFileSync(
      TmpFileNameMange,
      JSON.stringify({ i: index, total, md5 })
    );
    if (index === total) {
      FS.renameSync(TmpFileName, FileName);
      FS.unlinkSync(TmpFileNameMange);
      resolve();
      return;
    }
    resolve(index);
  });
};

前端js代码

 async submit() {
      let file = this.$refs.file.files[0];
      this.upload(file);
    },
    async upload(file, index = 0) {
      // 获取文件大小
      let fileSize = file.size;
      // 每个块的大小
      let chunkSize = 1024 * 1024 * 0.0005;
      // 共多少块
      let chunkNum = Math.ceil(fileSize / chunkSize);
      // 定义formData对象
      let formData = new FormData();
      // 定义结束位置;
      let end = index + 1;
      // 片段是否最后一片,如果不是最后一片,那么就是每片的位置
      if (end < chunkNum) end = end * chunkSize;
      // 如果是最后一片,结束位置等于文件最后的位置
      else end = fileSize;
      // 获取单个切片
      let chunData = file.slice(index * chunkSize, end);
      // 储存单个切片
      formData.append("file", chunData, file.name);
      formData.append("index", index + 1); //第几片
      formData.append("total", chunkNum); //第几片
      formData.append('md5',md5(file))
      let { data } = await axios({
        url: "http://127.0.0.1:3000/api/chunkUpload",
        method: "post",
        data: formData,
        headers: { token: "token" }
      });
      // 后台需要返回当前切片位置
      index = data.data - 0; 
      if (end < fileSize) this.upload(file, index);
    }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • node复习笔记 第一天 前端向后台服务器发送请求的类型get: 用来获取数据post: 用来提交数据 前端发送请...
    果木山阅读 777评论 0 0
  • NodeJS的基本概念 NodeJS是什么? `官网:https://nodejs.org/en/ Node.js...
    getElementsByMK阅读 16,146评论 0 22
  • nodejs模块 nodejs系统自带的模块:http:协议请求模块;创建服务器:http.createServe...
    果木山阅读 989评论 0 0
  • 个人入门学习用笔记、不过多作为参考依据。如有错误欢迎斧正 目录 简书好像不支持锚点、复制搜索(反正也是写给我自己看...
    kirito_song阅读 2,654评论 1 37
  • # Ajax标签(空格分隔): 笔记整理---[TOC]### 从输入网址开始:- 在学习ajax之前,你应该先了...
    V8阅读 349评论 1 0

友情链接更多精彩内容