js学习之随心所欲

文件分段上传

2019-06-05  本文已影响14人  摆渡侠

文件切分上传

昨天有些文艺了。。。今天来点儿干货,总结一下大文件切割上传问题。

emmmmmmm......

好像直接上代码就可以了,话不多说

HTML:

<div class="wrapper">
  <input id="file" type="file" onchange="window.upload()"/>
  <div class="count">
    <div class="current"></div>
  </div>
</div>

CSS:

.wrapper{
  display: flex;
  flex-direction: column;
  align-items: center;
}
    
.count{
  margin-top: 20px;
  width: 400px;
  height: 8px;
  line-height: 8px;
  background-color: #eeeeee;
}
    
.current{
  display: inline-block;
  height: 8px;
  background-color: #00cc00;
  transition: 0.5s;
  text-align: center;
  font-size: 12px;
}

JAVASCRIPT:

(function(){
    var start = 0,  // 文件片段开始点
      length = 100,  // 文件片段size
      end = start + length, // 文件片段结束点
      count = 0,     // 文件总大小(size)
      blob = null,   // 文件片段流
      blobId = 1,     // 片段ID
      isLastBlob = 0, // 是否已经将所有文件都上传完成 0 :未完成, 1: 完成
      formData = null,  // formData实例
      file = null,      // 当前选择的文件
      xhr =null,
      pecentElement = document.querySelector('.current');

    window.upload = function upload () {
      file = document.querySelector('#file').files[0];
      count = file.size;
      up();
    }
    
    function up() {
      if(start < count) {
        blob = file.slice(start, end);
        if(start + length > count) {
          isLastBlob = 1;
        }
        // 创建formData将数据append 进去,最后一起send到服务端。
        formData = new FormData();
        formData.append('blob', blob);
        formData.append('fileName', file.name);
        formData.append('blobId', blobId);
        formData.append('isComplate', isLastBlob);

        // 写了两个方法, ajax 为ajax发送数据上传,simulateAjax 为模拟ajax上传,因为没有后端接口
        // ajax(formData);
        simulateAjax();
      }
    }
    
    function ajax(formData){
      xhr = new XMLHttpRequest();
      xhr.open('xxxx/xxx', 'POST');
      xhr.onload = function () {
        if(xhr.status >= 200 && xhr.status < 300) {
          calculatePecent();
          up();
        }else {
          alert('upload filed!')
          start = 0;
        }
      }
      xhr.send(formData);
    }
    
    function simulateAjax() {
      new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(200);
          //reject(500);
        }, 2000)
      }).then(() => {
        calculatePecent();
        up();
      }, () => {
        alert('upload filed!')
        start = 0;
      })
    }

    function calculatePecent() {
      // 成功之后片段开始等于上一次结束位置, 片段结束为开始位置加上片段长度
      start = end;
      end = start + length;
      if(start > count){
        start = count;
        end = count
      }
      // 展示进度条,代表上传了多少
      pecentElement.style.width = parseInt(start / count * 100) + '%';
      pecentElement.innerHTML = parseInt(start / count * 100) + '%';
    }
  })()  

总结: 文件分段上传核心,为slice将数据流分割,这种是针对上传的文件,如果单纯上传超大文件,不看上传了多少,可以将文件分割,同时发起多个http请求,并发上传文件片段。 这边没有介绍 xhr.onprogress这个东西,是ajax 进度事件,这个也可以简单实现进度条问题,slice主要偏重文件按照一定大小顺序上传, onprogress 主要是针对上传时带宽大小,看文件上传速度,和大小,按照现在中国宽带发展情况,未来不会因为网速问题,需要分段上传文件。

有问题的同学,欢迎留言讨论。

上一篇 下一篇

猜你喜欢

热点阅读