前端 大文件断点续传

231 阅读2分钟

前端大文件上传,使用webuploader+jquery, webuploader链接:fex.baidu.com/webuploader…

话不多说,直接上代码

HTML代码如下

<el-form-item label="文件名称" required label-width="80"> <el-input v-model="fileName" disabled style="width: 200px" ></el-input> </el-form-item> <el-form-item label="选择文件" required label-width="80"> <el-button style="padding: 0" class="selectFile" :disabled="false" type="primary" size="mini" ref="selectFile" > 选择文件 </el-button> </el-form-item> <el-progress v-if="upJd" :percentage="percentage"></el-progress> `

<el-button @click="resume">开始 <el-button @click="stop">取消

`

//引入webuploader插件与样式

import WebUploader from "webuploader";
import "webuploader/dist/webuploader.css";

JS代码如下

data() { return {

  fileName: "", // 文件名称
  uploader: null,
  file: {},
  filepath: "", // 上级名称
  filepid: "", // 上级id
  resourceId: "", // 资源id
  fileMd5: "", // 文件md5
  showJY: false,
  percentage: 0,
  upJd: false,
  showHc: false,
  jmWay: "",
};

},

// 初始化webuploder

`initWebUpload() {
  if (this.uploader) {
    this.uploader.destroy();
  }
  setTimeout(() => {
    const uploader = (this.uploader = WebUploader.create({
      auto: false, // 选完文件后,是否自动上传
      server: "xxxxxx", // 文件接收服务端
      pick: {
        id: this.$refs.selectFile.$el, // 选择文件的按钮
        multiple: false, // 是否多文件上传 默认false
      },
      headers: {
        token: sessionStorage.getItem("token"),
      },
      // accept: this.getAccept(this.accept), // 允许选择文件格式。
      threads: 3,
      // fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小
      chunked: true, // 分片上传
      formData: {
        fileMd5: this.fileMd5,
        resourceId: this.resourceId,
      },
      chunkSize: 3000000, // 分片大小
      duplicate: false, // 重复上传
      prepareNextFile: true,
    }));
    const fun = [
      "fileQueued",
      "uploadStart",
      "uploadProgress",
      "uploadSuccess",
      "error",
      "uploadError",
      "uploadBeforeSend",
    ];
    for (const item of fun) {
      uploader.on(item, this[item]);
    }
    return uploader;
  }, 10);
},`

   // 当有文件被添加进队列的时候,添加到页面预览
fileQueued(file) {
  console.log(file, "file");
  const { name, size, id } = file;
  this.fileName = name;
  this.file = file;
  this.showJY = true;
  this.uploader.md5File(file).then((res) => {
    this.showJY = false;
    this.fileMd5 = res;
  });
},
uploadBeforeSend(block, data) {
  data.fileMd5 = this.fileMd5;
  data.chunk = block.chunk;
  data.resourceId = this.resourceId;
},
// 文件上传过程中创建进度条实时显示。
uploadProgress(file, percentage) {
  this.percentage = parseInt(percentage * 100).toFixed(2);
},
// 文件上传成功
uploadSuccess(file, res) {
  this.showHc = true;
  io.post(
    "resourcesHDFS/upload/mergeChunks",
    {
      fileMd5: this.fileMd5,
      resourceId: this.resourceId,
      cipher: this.jmWay,
    },
    (res) => {
      this.$message({
        message: "上传成功",
        type: "success",
      });
      this.showHc = false;
      this.fileMd5 = "";
      this.resourceId = "";
      this.file = "";
      this.fileName = "";
      this.upJd = false;
      this.showJY = false;
      this.jmWay = "";
      this.uploader.destroy();
      this.dialogFormVisible = false;
      this._getList(true);
    }
  ).catch((e) => {
    console.log(e,'eeeeeeeee')
    this.$message({
      message: "合成失败",
      type: "error",
    });
    this.showHc = false;
    this.fileMd5 = "";
    this.resourceId = "";
    this.file = "";
    this.fileName = "";
    this.upJd = false;
    this.showJY = false;
    this.jmWay = "";
    this.uploader.destroy();
    this.dialogFormVisible = false;
    this._getList(true);
  });
},
uploadError(data) {
  this.$message({
    message: "上传失败",
    type: "error",
  });
  this.fileMd5 = "";
  this.resourceId = "";
  this.file = "";
  this.fileName = "";
  this.upJd = false;
  this.jmWay = "";
  this.showJY = false;
  this.uploader.stop(true);
  this.uploader.destroy();
  this.dialogFormVisible = false;
  this._getList(true);
  this.showHc = false;
},
// 开始
resume() {
  if (this.fileMd5 != "" && this.file != {}) {
    let num = Math.ceil(this.file.size / 3000000);
    let it = {
      name: this.file.name,
      fileMd5: this.fileMd5,
      fileSize: this.file.size,
      chunkNum: num,
      path: this.filepath,
      pid: this.filepid,
      cipher: this.jmWay,
    };
    // 选择文件注册文件判断文件是否已经存在
    io.post("resourcesHDFS/chuck/register", it, (res) => {
      this.resourceId = res.data; // 获取文件id
      this.uploader.upload(this.file);
      this.upJd = true;
    }).catch((e) => {
      this.$message({
        message: e.msg,
        type: "warning",
      });
      this.file = "";
      this.fileName = "";
    });
  } else {
    this.$message({
      message: "请选择文件!",
      type: "warning",
    });
  }
},
// 暂停
stop() {
  this.fileMd5 = "";
  this.resourceId = "";
  this.file = "";
  this.fileName = "";
  this.upJd = false;
  this.jmWay = "";
  this.showJY = false;
  this.uploader.stop(true);
  this.uploader.destroy();
  this.dialogFormVisible = false;
  this._getList(true);
  this.showHc = false;
},

到此为文件上传以及暂停,断点续传如下

这里需要引入jq
import $ from "jquery";
import WebUploader from "webuploader";
import "webuploader/dist/webuploader.css";

//初始化webuploder

initWebUploads() {
  let that = this;
  if (this.uploaders) {
    this.uploaders.destroy();
  }
   WebUploader.Uploader.register(
    {
      name: "contractUpload",
      "before-send": "beforeSend",
    },
    {
      beforeSend: function (block) {
        var task = $.Deferred();
        let dta = {
          fileMd5: that.fileMd5,
          chunk: block.chunk,
          resourceId: that.fileData.id,
        };
        block.fileMd5 = that.fileMd5;
        // data.chunk = block.chunk;
        block.resourceId = that.fileData.id;
        $.ajax({
          type: "get",
          url: "/dolphinscheduler/resourcesHDFS/chuck/check",
          headers: {
            token: sessionStorage.getItem("token"),
          },
          data: dta,
          dataType: "json",
          success: function (response) {
            if (response.data) {
              // 分块存在,跳过该分块
              task.reject();
            } else {
              // 分块不存在或不完整,重新发送
              task.resolve();
            }
          },
        });
        return $.when(task)
      },
    }
  );
  setTimeout(() => {
    const uploaders = (that.uploaders = WebUploader.create({
      auto: false, // 选完文件后,是否自动上传
      server: "/dolphinscheduler/resourcesHDFS", // 文件接收服务端
      pick: {
        id: that.$refs.nextFile.$el, // 选择文件的按钮
        multiple: that, // 是否多文件上传 默认false
      },
      headers: {
        token: sessionStorage.getItem("token"),
      },
      // accept: this.getAccept(this.accept), // 允许选择文件格式。
      threads: 3,
      fileSingleSizeLimit: that.fileSingleSizeLimit, // 限制单个上传图片的大小
      chunked: true, //分片上传
      chunkSize: 3000000, //分片大小
      duplicate: false, // 重复上传
    }));
    const fun = [
      "fileQueued",
      // "uploadStart",
      "uploadProgress",
      "uploadSuccess",
      "error",
      "uploadError",
      "uploadBeforeSend",
    ];
    for (const item of fun) {
      uploaders.on(item, this[item]);
    }
    return uploaders;
  }, 10);
},
// 当有文件被添加进队列的时候,添加到页面预览
fileQueued(file) {
  const { name, size, id } = file;
  this.file = file;
  this.showJYs = true;
  this.uploaders.md5File(file).then((res) => {
    this.showJYs = false;
    if (this.fileData.md5 != res) {
      this.$message({
        message: "续传文件不是原文件,请重新选择",
        type: "warning",
      });
      this.uploaders.removeFile(file, true);
    } else {
      this.fileMd5 = res;
      this.uploaders.upload(this.file);
      this.upJds = true;
    }
  });
},
uploadBeforeSend(block, data) {
  data.fileMd5 = this.fileMd5;
  data.chunk = block.chunk;
  data.resourceId = this.fileData.id;
},
// 文件上传过程中创建进度条实时显示。
uploadProgress(file, percentage) {
  this.percentages = parseInt(percentage * 100).toFixed(2);
},
// 文件上传成功
uploadSuccess(file, res) {
  console.log(res, "8989900");
  this.upHc = true;
  io.post(
    "resourcesHDFS/upload/mergeChunks",
    { fileMd5: this.fileMd5, resourceId: this.fileData.id },
    (res) => {
      this.$message({
        message: "上传成功",
        type: "success",
      });
      this.upHc = false;
      this.showUpFile = false;
      this.fileMd5 = "";
      this.file = "";
      this.fileData = {};
      this.upJds = false;
      this.showJYs = false;
      this.uploaders.destroy();
      this.$emit("on-update");
    }
  ).catch((e) => {
      this.$message({
        message: "合成失败",
        type: "error",
      });
      this.upHc = false;
      this.showUpFile = false;
      this.fileMd5 = "";
      this.file = "";
      this.fileData = {};
      this.upJds = false;
      this.showJYs = false;
      this.uploaders.destroy();
      this.$emit("on-update");
  });
},
uploadError(data) {
  this.$message({
    message:'上传失败',
    type:'error'
  })
  this.showUpFile = false;
  this.upHc = false;
  this.fileMd5 = "";
  this.file = "";
  this.fileData = {};
  this.upJds = false;
  this.showJYs = false;
  this.uploaders.stop(true);
  this.uploaders.destroy();
  this.$emit("on-update");
},

stops() {
  this.showUpFile = false;
  this.upHc = false;
  this.fileMd5 = "";
  this.file = "";
  this.fileData = {};
  this.upJds = false;
  this.showJYs = false;
  this.uploaders.stop(true);
  this.uploaders.destroy();
  this.$emit("on-update");
},

主要看webuploader文档,前端去需要配合后台共同完成实现大文件的上传