使用ali-oss阿里云服务分片上传(默认支持多线程)

项目里使用ali-oss,阿里云服务存文件。客户说上传太慢,这里分享一下自己总结的一些东西。

解决思路

  1. 接到需求首先看了一下,项目里使用的 browser-md5-file插件进获取文件md5码,这个插件处理速度属实感人。于是换了cnpm i -S spark-md5,自己测试300M文件速度直接比以前插件快一倍。
  2. 使用阿里云的分片上传 + 断点续传模式上传文件,官方说可以提高速度,具体没有试。

具体实现

  • Elementui 部分代码,不太懂的小伙伴可以去看看官网


上传按钮

//进度条部分
正在校验md5,请稍等……
  • 主要逻辑在upLoad函数里,对应上面elementui自定义上传,如下:
upLoad(item) {
  //获取文件md5码,用于后台校验
  this.checkMd5 = true;
  let fileReader = new FileReader();
  let dataFile = item.file
  let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
  let spark = new SparkMD5.ArrayBuffer();
  fileReader.readAsArrayBuffer(dataFile)
  fileReader.onload = (e) =>{
    spark.append(e.target.result);
    let md5 = spark.end()
    //请求是伪代码,根据自己项目去实现
    axios.get('/api',params:{md5})
    .then((info) => {
        //info是返回的文件信息
        if(info.id){ //文件在服务器已经存在
        } else {
          //文件不存在,执行上传
          let checkpoint={}; //标记,记录断点信息
          async function resumeUpload() {
            for (let i = 0; i < 5; i++) {
              try {
                const result = await client.multipartUpload(filePath,file, {
                  checkpoint,
                  async progress(percentage, cpt) {
                    // console.log(percentage, cpt)
                    checkpoint = cpt;
                    that.showProgress = true;
                    that.progress = Math.floor(percentage * 100);
                  },
                })
                console.log(result); //可以根据result里的内容做一些别的事情,比如预览文件等。
                break; // break if success
              } catch (e) {
                console.log(e);
              }
            }
          }
          resumeUpload();
        }
    })
  }
}

补充 2021.4.8,获取md5值一样的问题

import SparkMD5 from 'spark-md5';

const getMd5 = function (file) {
    return new Promise((resolve, reject) => {
        var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
        // file = file,
        chunkSize = 2097152,                             // Read in chunks of 2MB
        chunks = Math.ceil(file.size / chunkSize),
        currentChunk = 0,
        spark = new SparkMD5.ArrayBuffer(),
        fileReader = new FileReader();

        fileReader.onload = function (e) {
          // console.log('read chunk nr', currentChunk + 1, 'of', chunks);
          spark.append(e.target.result);                   // Append array buffer
          currentChunk++;

          if (currentChunk < chunks) {
              loadNext();
          } else {
              console.log('finished loading');
              // console.info('computed hash', spark.end());  // Compute hash
              resolve(spark.end())
          }
        };

        fileReader.onerror = function () {
          reject('计算失败')
          console.warn('oops, something went wrong.');
        };
        function loadNext() {
            var start = currentChunk * chunkSize,
                end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;

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

        loadNext();
    })
}
//使用1
getMd5(file).then(res => this.md5 = res)

//使用2
//可以在elementui等上传组件的beforeupload里执行
async function asdf(file){
    this.md5 = await getMd5(file)
}

你可能感兴趣的:(使用ali-oss阿里云服务分片上传(默认支持多线程))