前端分片上传

需求描述: 前端获取文件md5码且实现分片上传

步骤:

一:获取文件md5

    1.插件spark-md5,还有另外一个插件(browser-md5-file)但是不兼容ie11,至于其他ie版本,未测

    2.以分片的方式获取文件MD5码,一下为封装的方法:

 /**

   * @param file 文件

   * @param chunkSize 分片大小

   * @returns Promise

   */

  const getFileMd5 = (file, chunkSize) => {

    return new Promise((resolve, reject) => {

      setSpin({

        spinning: true,

        tip: '正在努力导入应用数据,请耐心等待......',

      });

      let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;

      let chunks = Math.ceil(file.size / chunkSize); // 总分片数

      let currentChunk = 0; 

      let spark = new SparkMD5.ArrayBuffer();

      let fileReader = new FileReader();

      fileReader.onload = function(e) {

        spark.append(e.target.result);

        currentChunk++;

        if (currentChunk < chunks) {

          loadNext();

        } else {

          let md5 = spark.end(); // 结束时调用

          resolve(md5);

        }

      };

      fileReader.onerror = function(e) {

        reject(e);

      };

      // 文件分片

      function loadNext() {

        let start = currentChunk * chunkSize;

        let end = start + chunkSize;

        if (end > file.size) {

          end = file.size;

        }

        fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));

      }

      loadNext();

    });

  }

二、文件分片调取接口

  /**

   *

   * @param {Object} file 文件

   * @param {Number} index 下标

   * @param {Number} chunkSize 分片数

   * @param {String} md5 md5码

   */

  const fileImport = (file, index, chunkSize, md5) => { // 获取MD5

    const chunks = Math.ceil(file.size / chunkSize); // 防止文件截取不完整 所以向上取整

    if (file) {

      let upSize = index * chunkSize;

      if (index > chunks - 1) {

        return;

      }

      let blob = file.slice(upSize, upSize + chunkSize); // 截取文件

      try {

        let formData = new FormData();

        formData.append('file', blob);

        formData.append('md5', md5);

        formData.append('chunk', index);

        formData.append('chunks', chunks);

        sliceImportVisualization(formData).then(async res => {

          if (res?.isSuccess) {

            await fileImport(file, ++index, chunkSize, md5); // 在上一片传输完成后再调用 切记 切记

            const { data = {} } = res;

            const { file_name } = data;

            if (file_name) {

              importVisualization({ file_name }).then(res => {

                setSpin({spinning: false});

              });

            }

          }

        });

      } catch (err) {

        console.log('分片上传错误...', err);

      }

    }

  };

你可能感兴趣的:(前端分片上传)