文件上传实现方案概述

文件上传是很多项目中用到的功能,最近项目要实现文件上传下载,分片上传、断点续传、异步导出、同步导出等功能,所以去研究研究以下该内容,并将学习到的知识汇总写出来分享一下,以我自己的理解写出来。
文件上传的实现常见的有以下几种:
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检查、分片上传、断点续传,前后端代码及原理图。
以尽量追求详细、通俗易懂。

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