文件上傳實現方案概述

文件上傳是很多項目中用到的功能,最近項目要實現文件上傳下載,分片上傳、斷點續傳、異步導出、同步導出等功能,所以去研究研究以下該內容,並將學習到的知識彙總寫出來分享一下,以我自己的理解寫出來。
文件上傳的實現常見的有以下幾種:
1、基於aioxs和jquery的上傳;
2、基於element-ui中的uploader的上傳;
3、基於webuploader的上傳。
前兩種基本相同,element-ui有ui樣式,其最終的上傳還是利用到aioxs和jquery的。1和2的優點是簡單,缺點是對大文件的上傳、網絡故障重新上傳沒有支持,需要自己去實現,工作量較大,在往後的文章中會介紹基於兩者的斷點續傳、分片上傳的實現。webuploader是百度的一個文件上傳框架,js的支持,ui樣式需要自己去添加實現,其可以叫輕鬆實現斷點續傳、分片上傳的功能。斷點續傳、分片上傳的應用場合是大文件上傳。而小文件的上傳利用element-ui實現較輕量級,其ui也支持拖拽上傳、頭像上傳、縮略圖等。
下面分別大概介紹下這三者的一些基礎理解:
1、基於aioxs和jquery的上傳
代碼如下:

<template>
  <div class="hello">
    <input  class="file" name="file"  type="file"   accept="image/png, image/gif, image/jpeg"   @change="update" />
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  methods: {
    update(e) {
      let file = e.target.files[0];
      alert(file.name);
      console.log(file);
      let param = new FormData(); //創建form對象
      param.append("file", file); //通過append向form對象添加數據
      console.log(param.get("file")); //FormData私有類對象,訪問不到,可以通過get判斷值是否傳進去
      let config = {
        headers: { "Content-Type": "multipart/form-data" }
      }; //添加請求頭
      this.$http
        .post("http://127.0.0.1:8081/data/up", param, config)
        .then(response => {
          console.log(response.data);
        }).catch(
          error=>{
            alert("失敗");
          }
        );
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
</style>

2、基於element-ui中的uploader的上傳

實現的效果:
在這裏插入圖片描述

<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :before-remove="beforeRemove"
  multiple
  :limit="3"
  :on-exceed="handleExceed"
  :file-list="fileList">
  <el-button size="small" type="primary">點擊上傳</el-button>
  <div slot="tip" class="el-upload__tip">只能上傳jpg/png文件,且不超過500kb</div>
</el-upload>
<script>
  export default {
    data() {
      return {
        fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
      };
    },
    methods: {
      handleRemove(file, fileList) {
        console.log(file, fileList);
      },
      handlePreview(file) {
        console.log(file);
      },
      handleExceed(files, fileList) {
        this.$message.warning(`當前限制選擇 3 個文件,本次選擇了 ${files.length} 個文件,共選擇了 ${files.length + fileList.length} 個文件`);
      },
      beforeRemove(file, fileList) {
        return this.$confirm(`確定移除 ${ file.name }?`);
      }
    }
  }
</script>

這裏的代碼只是選中文件,然後展示出來,並沒有發送請求到服務端,所有需要添加基於aioxs和jquery的上傳,將data中的filelist發送到服務端。
element-ui官網

3、基於webuploader的上傳
html部分

<div id="uploader" class="wu-example">
    <!--用來存放文件信息-->
    <div id="thelist" class="uploader-list"></div>
    <div class="btns">
        <div id="picker">選擇文件</div>
        <button id="ctlBtn" class="btn btn-default">開始上傳</button>
    </div>
</div>

創建webuploader對象,配置對象參數。

var uploader = WebUploader.create({

    // swf文件路徑
    swf: BASE_URL + '/js/Uploader.swf',

    // 文件接收服務端。
    server: 'http://webuploader.duapp.com/server/fileupload.php',

    // 選擇文件的按鈕。可選。
    // 內部根據當前運行是創建,可能是input元素,也可能是flash.
    pick: '#picker',
    // 不壓縮image, 默認如果是jpeg,文件上傳前會壓縮一把再上傳!
    resize: false
});
// 當有文件被添加進隊列的時候
uploader.on( 'fileQueued', function( file ) {
    $list.append( '<div id="' + file.id + '" class="item">' +
        '<h4 class="info">' + file.name + '</h4>' +
        '<p class="state">等待上傳...</p>' +
    '</div>' );
});
// 文件上傳過程中創建進度條實時顯示。
uploader.on( 'uploadProgress', function( file, percentage ) {
    var $li = $( '#'+file.id ),
        $percent = $li.find('.progress .progress-bar');
    // 避免重複創建
    if ( !$percent.length ) {
        $percent = $('<div class="progress progress-striped active">' +
          '<div class="progress-bar" role="progressbar" style="width: 0%">' +
          '</div>' +
        '</div>').appendTo( $li ).find('.progress-bar');
    }

    $li.find('p.state').text('上傳中');

    $percent.css( 'width', percentage * 100 + '%' );
});

文件上傳失敗會派送uploadError事件,成功則派送uploadSuccess事件。不管成功或者失敗,在文件上傳完後都會觸發uploadComplete事件。

uploader.on( 'uploadSuccess', function( file ) {
    $( '#'+file.id ).find('p.state').text('已上傳');
});

uploader.on( 'uploadError', function( file ) {
    $( '#'+file.id ).find('p.state').text('上傳出錯');
});

uploader.on( 'uploadComplete', function( file ) {
    $( '#'+file.id ).find('.progress').fadeOut();
});

最重要的是在創建webuploader對象時沒有設置自動上傳時需要觸發上傳,設置了自動上傳就不需要設置觸發。
觸發上傳的api

 uploader.upload();

以上時webuploader的基本使用,它還包括:
在這裏插入圖片描述
md5文件檢查校驗:對md5文件相同的可以跳過不上傳,避免相同文件的上傳。
分片上傳、斷點續傳的支持。關於這些內容會在往後的文章中給出。
webuploader官網
這裏只是概述性的描述文件上傳的內容,提供一個思路,後面會一一給出具體的實現代碼及原理說明等。
往後的內容包括:
1、原生的非組件的實現分片上傳及斷點續傳,前後端代碼及原理圖;
2、基於webuploader的MD5檢查、分片上傳、斷點續傳,前後端代碼及原理圖。
以儘量追求詳細、通俗易懂。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章