首页 web前端 js教程 webuploader文件上传组件的开发实例

webuploader文件上传组件的开发实例

Feb 02, 2018 pm 01:28 PM
web 开发实例

最近项目中需要用到百度的webuploader大文件的分片上传,对接后端的fastdfs,于是着手写了这个文件上传的小插件,步骤很简单,但是其中猜到的坑也不少,本文主要介绍了vue webuploader 文件上传组件开发,小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助到大家。

详细如下:

一、封装组件

引入百度提供的webuploader.js、Uploader.swf

css样式就直接写在组件里面了 


<template>
 <p>
  <p id="list" class="uploader-list"></p>
  <p id="wrapper">
   <p class="uploader-container">
    <p :id="id" limitSize="1" :ext="ext"></p>
    <el-button style="margin-bottom:10px;float:left;" size="small" :loading="uploadLoading" type="success" @click="start">上传到服务器</el-button>
    <el-button style="margin-left: 20px;margin-bottom:10px;float:left;" :disabled="stopBtn" size="small" type="danger" @click="stop">暂停上传</el-button>
   </p>
  </p>
  <p class="el-upload__tip">{{tip}}</p>
  <p class="file-list">
   <ul class="el-upload-list el-upload-list--text">
    <li v-for="file in fileList" :class="[&#39;el-upload-list__item&#39;, &#39;is-&#39; + file.status]" :key="file">
     <a class="el-upload-list__item-name">
      <i class="el-icon-document"></i>{{file.name}}
     </a>
     <label class="el-upload-list__item-status-label">
      <i :class="{&#39;el-icon-upload-success&#39;: true,&#39;el-icon-circle-check&#39;: listType === &#39;text&#39;,
     &#39;el-icon-check&#39;: [&#39;picture-card&#39;, &#39;picture&#39;].indexOf(listType) > -1}"></i>
     </label>
     <i class="el-icon-close" @click="removeFile(file)"></i>
     <el-progress
      v-if="file.status === &#39;uploading&#39;"
      :type="listType === &#39;picture-card&#39; ? &#39;circle&#39; : &#39;line&#39;"
      :stroke-width="listType === &#39;picture-card&#39; ? 6 : 2"
      :percentage="file.percentage">
     </el-progress>
    </li>
   </ul>
  </p>
 </p>
</template>
<script>
 import &#39;../js/jquery.js&#39;
 import &#39;../js/webuploader.js&#39;
 import { Base64 } from &#39;js-base64&#39;
 import CryptoJS from &#39;crypto-js&#39;;

 export default{
  name: &#39;fileUpload&#39;,
  props: {
   id: {
    type: String,
    default: function(){
     return "filePicker";
    }
   },
   //上传提示
   tip: {
    type: String,
    default: function(){
     return "";
    }
   },
   //文件后缀名限制
   ext: {
    type: String,
    default: function(){
     return "jpg,jpeg,png,pdf,mp4,avi.mp3";
    }
   },
   //分片大小设置
   chunkSize: {
    type: Number,
    default: function(){
     return 2097152;
    }
   },
   //分片上传重试次数
   chunkRetry: {
    type: Number,
    default: function(){
     return 1;
    }
   },
   //是否自动上传
   auto: {
    type: Boolean,
    default: function(){
     return false;
    }
   },
   //上传文件大小限制
   sizeLimit: {
    type: Number,
    default: function(){
     return 209715200;
    }
   },
   //上传文件数量限制
   countLimit: {
    type: Number,
    default: function(){
     return 5;
    }
   }
  },
  data(){
   return{
    appId: AppConfig.appId,
    securityKey: AppConfig.securityKey,
    checkUrl: AppConfig.checkUrl,
    uploadUrl: AppConfig.uploadUrl,
    mergeUrl: AppConfig.mergeUrl,
    previewName: &#39;选择文件&#39;,
    wul_fileMd5: &#39;&#39;,
    wul_size: 0,
    wul_fileName: &#39;&#39;,
    wul_chunk: 0,
    wul_uploader: &#39;&#39;,
    fileList: [],
    listType: &#39;text&#39;,
    percentage: 0,
    fileObject: {
     uid: &#39;&#39;,
     name: &#39;&#39;,
     ext: &#39;&#39;,
     type: &#39;&#39;,
     status: &#39;&#39;,
     percentage: 0,
     url: &#39;&#39;
    },
    uploadLoading: false,
    stopBtn: true
   }
  },
  methods: {
   /**
    * 获取当前上传列表中的文件
    * @returns {Array|*}
    */
   getFileList: function(){
    return this.fileList;
   },
   //绑定事件
   wul_init: function() {
    //提示只能选择一个文件
    this.wul_uploader.on(&#39;filesQueued&#39;, function (files) {
     if (files.length > 1) {
      this.$message({
       message: &#39;请选择一张图片&#39;,
       type: &#39;error&#39;
      });
      for (var i = 0; i < files.length; i++) {
       this.wul_uploader.cancelFile(files[i]);
      }
      this.wul_uploader.reset();
      this.wul_fileMd5 = "";
      this.wul_size = 0;
      this.wul_fileName = "";
      this.wul_chunk = 0;  //当前切片数
     }else{
      if( this.fileList.length == this.countLimit ){
       this.$message({
        message: &#39;已经达到上传文件限制数量&#39;,
        type: &#39;error&#39;
       });
      }else{
       //此时往需要上传的文件列表中添加文件
       let file = {
        uid: Date.now() + this.tempIndex++,
        name: files[0].name,
        type: files[0].type,
        ext: files[0].ext,
        status: "ready",
        percentage: 0
       }
       this.fileObject = file;
       this.fileList.push(this.fileObject);
      }
     }
    }.bind(this));

    //文件校验格式和大小
    this.wul_uploader.on(&#39;error&#39;, function (type) {
      debugger
     if (type == &#39;Q_EXCEED_SIZE_LIMIT&#39;) {
      this.$message({
       message: &#39;文件超过指定大小&#39;,
       type: &#39;error&#39;
      });
     }
     if (type == &#39;Q_TYPE_DENIED&#39;) {
      this.$message({
       message: &#39;文件格式错误,请选择文件&#39;,
       type: &#39;error&#39;
      });
     }
     if (type == &#39;F_EXCEED_SIZE&#39;) {
      this.$message({
       message: "文件超过" + this.sizeLimit / 1024 / 1024 + "M",
       type: &#39;error&#39;
      });
     }
    }.bind(this));

    //上传进度
    this.wul_uploader.on(&#39;uploadProgress&#39;, function (file, percentage) {
     this.percentage = percentage * 100;
     this.fileObject.status = "uploading";
     this.fileObject.percentage = this.percentage;
     console.log(this.fileObject.percentage);
    }.bind(this));

    //每次切片上传完成之后的判断
    this.wul_uploader.on(&#39;uploadAccept&#39;, function (object, ret) {
     if (ret.responseCode != 0) {
      this.wul_uploader.cancelFile(this.wul_uploader.getFiles()[0].id);
     }
    });

    this.wul_uploader.on(&#39;uploadBeforeSend&#39;, function(object, data, headers) {
     console.log(data);
    });
   },

   option: function(key, val) {
    this.wul_uploader.option(key, val);
    var options = this.wul_uploader.options;
    this.wul_uploader.destroy();  //注销uploader
    this.wul_uploader = WebUploader.create(options);
    this.wul_init();
   },
   start: function(){
    if(this.wul_uploader.getFiles()[0] != null) {
     this.wul_uploader.upload(this.wul_uploader.getFiles()[0].id);
     this.uploadLoading = true;
     this.stopBtn = false;
    } else {
     this.$message({
      message: "请选择上传文件",
      type: &#39;error&#39;
     });
    }
   },
   stop: function(){
    this.wul_uploader.cancelFile(this.wul_uploader.getFiles()[0].id);
   },
   removeFile: function(file){
    this.fileList.splice(this.fileList.indexOf(file), 1);
   },
   change: function(){
    this.option(&#39;accept&#39;, {
     title: &#39;Images&#39;,
     extensions: &#39;gif,jpg,jpeg,bmp,png&#39;
    });
   }
  },
  mounted(){
   WebUploader.Uploader.register({
    "before-send-file": "beforeSendFile",
    "before-send": "beforeSend",
    "after-send-file": "afterSendFile",
   }, {
    beforeSendFile: function (file) {
     var deferred = WebUploader.Deferred();
     this.wul_uploader.md5File(file).then(function (val) {
      this.wul_fileMd5 = val;
      this.wul_size = file.size;
      this.wul_fileName = file.name;
      var timestamp = Date.parse(new Date()) / 1000;
      var signParam = "{chunkSize=" + this.chunkSize + ", fileMd5=" + this.wul_fileMd5 + ", size=" + this.wul_size + ", timestamp=" + timestamp + "}";
      var sign = Base64.encode(CryptoJS.HmacSHA1(signParam, this.securityKey));
      // 获取断点续传位置
      jQuery.ajax({
       type: "POST",
       // 测试
       url: this.checkUrl,
       data: {
        // 文件大小
        size: this.wul_size,
        // 文件唯一标记
        fileMd5: this.wul_fileMd5,
        // 切片大小
        chunkSize: this.chunkSize,
        // 签名
        sign: sign,
        // 应用分配id
        appId: this.appId,
        // 当前时间戳
        timestamp: timestamp

       },
       dataType: "json",
       // 上传失败
       error: function (XMLHttpRequest, textStatus, errorThrown) {
        this.$message({
         message: "上传失败...",
         type: &#39;error&#39;
        });
        this.uploadLoading = false;
        this.stopBtn = true;
       }.bind(this),
       success: function (response) {
        if (response.responseCode == 0) { // 切片获取成功
         this.wul_chunk = response.chunk;
         deferred.resolve();
        } else { // 切片获取失败,请求成功
         this.wul_uploader.cancelFile(file);  //取消文件上传
         this.$message({
          message: "切片检查失败,请联系管理员",
          type: &#39;error&#39;
         });
         deferred.resolve();
         this.uploadLoading = false;
         this.stopBtn = true;
        }
       }.bind(this)
      });
      return deferred.promise();
     }.bind(this));
     return deferred.promise();
    }.bind(this),
    beforeSend: function (block) {
     var deferred = WebUploader.Deferred();
     if (block.chunk < this.wul_chunk) {
      return deferred.reject();
     }
     this.wul_uploader.md5File(block.blob).then(function (chunkMd5) {
      var timestamp = Date.parse(new Date()) / 1000;
      var signParam = &#39;{chunk=&#39; + block.chunk + &#39;, chunkMd5=&#39; + chunkMd5 + &#39;, chunkSize=&#39; + this.chunkSize + &#39;, fileMd5=&#39; + this.wul_fileMd5 + &#39;, size=&#39; + this.wul_size + &#39;, timestamp=&#39; + timestamp + &#39;}&#39;;
      var signTemp = CryptoJS.HmacSHA1(signParam, this.securityKey);
      var sign = Base64.encode(signTemp);  //获取sign值
      this.wul_uploader.options.formData = {
       &#39;timestamp&#39;: timestamp,
       &#39;appId&#39;: this.appId,
       &#39;chunk&#39;: block.chunk,
       &#39;chunkSize&#39;: this.chunkSize,
       &#39;fileMd5&#39;: this.wul_fileMd5,
       &#39;chunkMd5&#39;: chunkMd5,
       &#39;size&#39;: this.wul_size,
       &#39;sign&#39;: sign
      };
      deferred.resolve();
     }.bind(this))
     return deferred.promise();
    }.bind(this),
    afterSendFile: function (file) {
     var timestamp = Date.parse(new Date()) / 1000;
     var signParam = "{chunkSize=" + this.chunkSize + ", fileMd5=" + this.wul_fileMd5 + ", fileName=" + file.name + ", size=" + this.wul_size + ", timestamp=" + timestamp + "}";
     var sign = Base64.encode(CryptoJS.HmacSHA1(signParam, this.securityKey));
     // 如果分块上传成功,则通知后台合并分块
     jQuery.ajax({
      type: "POST",
      url: this.mergeUrl,
      data: {
       appId: this.appId,
       fileMd5: this.wul_fileMd5,
       fileName: file.name,
       chunkSize: this.chunkSize,
       sign: sign,
       size: this.wul_size,
       timestamp: timestamp
      },
      success: function (response) {
       if (response.responseCode == 0) {
        this.fileObject.status = "success";
        this.fileObject.percentage = 100;
        this.fileObject.url = response.filePath;
       } else {
        this.fileObject.status = "exception";
        this.$message({
         message: "上传失败,失败原因:" + response.responseMsg,
         type: &#39;error&#39;
        });
       }
       this.uploadLoading = false;
       this.stopBtn = true;
       this.wul_uploader.reset();
       this.wul_fileMd5 = "";
       this.wul_size = 0;
       this.wul_fileName = "";
       this.wul_chunk = 0;  //当前切片数
      }.bind(this)
     });
    }.bind(this)
   });
   this.wul_uploader = WebUploader.create({
    // swf文件路径
    swf: &#39;../js/Uploader.swf&#39;,
    // 文件接收服务端。
    server: this.uploadUrl,
    // 定义选择按钮
    pick: {
     "id": "#" + this.id,
     "innerHTML": this.previewName
    },
    // 自动上传
    auto: this.auto,
    // 禁止浏览器打开文件
    disableGlobalDnd: true,
    // 添加截图功能
    paste: &#39;#wrapper&#39;,
    // 定义拖动面板
    dnd: &#39;#wrapper&#39;,
    // 分片上传
    chunked: true,
    // 分片大小为2M
    chunkSize: this.chunkSize,
    // 分片上传失败重试次数
    chunkRetry: this.chunkRetry,
    // 图片不做压缩
    compress: false,
    // 队列设置10个,为了选择多个文件的时候能提示
    fileNumLimit: 10,
    // 提前准备好下一个文件
    prepareNextFile: true,
    // 限制单个文件大小
    fileSingleSizeLimit: this.sizeLimit,
    //线程数
    threads : 1,
    // 限制格式
    accept: {
     title: "access",
     extensions: this.ext
    }
   });
   this.wul_init();
  }
 }
</script>
<style>
 /* ----------------Reset Css--------------------- */
 html, body, p, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre,
 a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp,
 small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li,
 fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td,
 article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary,
 time, mark, audio, video, input {
  margin: 0;
  padding: 0;
  border: none;
  outline: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
 }

 html, body, form, fieldset, p, p, h1, h2, h3, h4, h5, h6 {
  -webkit-text-size-adjust: none;
 }

 article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
  display: block;
 }

 body {
  font-family: arial, sans-serif;
 }

 ol, ul {
  list-style: none;
 }

 blockquote, q {
  quotes: none;
 }

 blockquote:before, blockquote:after, q:before, q:after {
  content: &#39;&#39;;
  content: none;
 }

 ins {
  text-decoration: none;
 }

 del {
  text-decoration: line-through;
 }

 table {
  border-collapse: collapse;
  border-spacing: 0;
 }

 /* ------------ */
 #wrapper {
  width: 100%;
  margin: 0 auto;
  height: 35px;
 }

 .img-preview {
  width: 160px;
  height: 90px;
  margin-top: 1em;
  border: 1px solid #ccc;
 }

 .cropper-wraper {
  position: relative;
 }

 .upload-btn {
  background: #ffffff;
  border: 1px solid #cfcfcf;
  color: #565656;
  padding: 10px 18px;
  display: inline-block;
  border-radius: 3px;
  margin-left: 10px;
  cursor: pointer;
  font-size: 14px;

  position: absolute;
  right: 1em;
  bottom: 2em;
 }
 .upload-btn:hover {
  background: #f0f0f0;
 }
 .uploader-container{
  width: 100%;
  font-size: 10px;
 }

 .webuploader-container {
  position: relative;
  width: 100px;
  height: 21px;
  float: left;
 }
 .webuploader-element-invisible {
  position: absolute !important;
  clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
  clip: rect(1px,1px,1px,1px);
 }
 .webuploader-pick {
  position: relative;
  display: inline-block;
  cursor: pointer;
  background: #00b7ee;
  padding: 6px 15px;

  color: #fff;
  text-align: center;
  border-radius: 3px;
  overflow: hidden;
 }
 .webuploader-pick-hover {
  background: #00a2d4;
 }

 .webuploader-pick-disable {
  opacity: 0.6;
  pointer-events:none;
 }
 .file-list{
  width: 100%;
 }
</style>
登录后复制

二、导出组件


var fileUpload = require(&#39;./src/file_upload.vue&#39;);

module.exports = {
 fileUpload
}
登录后复制

三、demo 引用方式


<template>
 <p>
  <el-card class="box-card">
   <fileUpload ref="fileUpload" :ext="ext" :countLimit="5" :tip="tip">aaa</fileUpload>
  </el-card>
 </p>
</template>
<script>
 import {fileUpload} from &#39;@/components/fileUpload/index.js&#39;
 export default{
  name: &#39;hello&#39;,
  components: {fileUpload},
  data(){
   return{
    fileList: [],
    ext: &#39;png,jpg,jpeg,mp3,mp4,pdf&#39;,
    tip: &#39;可上传png/jpg/jpeg/mp3/mp4/pdf,大小不超过200M&#39;
   }
  },
  created(){

  },
  methods: {
   getFileList: function(){
    this.fileList = this.$refs.fileUpload.getFileList();
    console.log(this.fileList);
   }
  }
 }
</script>
登录后复制

四、运行效果图

相关推荐:

详解Bootstrap fileinput文件上传组件的实例

Fine Uploader文件上传组件应用介绍_PHP教程

vue阿里云上传组件详解

以上是webuploader文件上传组件的开发实例的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用python Flask实现日志在web网页实时更新显示 如何使用python Flask实现日志在web网页实时更新显示 May 17, 2023 am 11:07 AM

一、日志输出到文件使用模块:logging可以生成自定义等级日志,可以输出日志到指定路径日志等级:debug(调试日志)=5){clearTimeout(time)//如果连续10次获取的都是空日志清除定时任务}return}if(data.log_type==2){//如果获取到新日志for(i=0;i

Nginx的Web服务器caddy怎么使用 Nginx的Web服务器caddy怎么使用 May 30, 2023 pm 12:19 PM

Caddy简介Caddy是一款功能强大,扩展性高的Web服务器,目前在Github上已有38K Star。Caddy采用Go语言编写,可用于静态资源托管和反向代理。Caddy具有如下主要特性:对比Nginx复杂的配置,其独创的Caddyfile配置非常简单;可以通过其提供的AdminAPI实现动态修改配置;默认支持自动化HTTPS配置,能自动申请HTTPS证书并进行配置;能够扩展到数以万计的站点;可以在任意地方执行,没有额外的依赖;采用Go语言编写,内存安全更有保证。安装首先我们直接在CentO

如何使用Golang实现Web应用程序的表单验证 如何使用Golang实现Web应用程序的表单验证 Jun 24, 2023 am 09:08 AM

表单验证是Web应用程序开发中非常重要的一个环节,它能够在提交表单数据之前对数据进行有效性检查,避免应用程序出现安全漏洞和数据错误。使用Golang可以轻松地实现Web应用程序的表单验证,本文将介绍如何使用Golang来实现Web应用程序的表单验证。一、表单验证的基本要素在介绍如何实现表单验证之前,我们需要知道表单验证的基本要素是什么。表单元素:表单元素是指

Java API 开发中使用 Jetty7 进行 Web 服务器处理 Java API 开发中使用 Jetty7 进行 Web 服务器处理 Jun 18, 2023 am 10:42 AM

JavaAPI开发中使用Jetty7进行Web服务器处理随着互联网的发展,Web服务器已经成为了应用程序开发的核心部分,同时也是许多企业所关注的焦点。为了满足日益增长的业务需求,许多开发人员选择使用Jetty进行Web服务器开发,其灵活性和可扩展性受到了广泛的认可。本文将介绍如何在JavaAPI开发中使用Jetty7进行We

Web 端实时防挡脸弹幕(基于机器学习) Web 端实时防挡脸弹幕(基于机器学习) Jun 10, 2023 pm 01:03 PM

防挡脸弹幕,即大量弹幕飘过,但不会遮挡视频画面中的人物,看起来像是从人物背后飘过去的。机器学习已经火了好几年了,但很多人都不知道浏览器中也能运行这些能力;本文介绍在视频弹幕方面的实践优化过程,文末列举了一些本方案可适用的场景,期望能开启一些脑洞。mediapipeDemo(https://google.github.io/mediapipe/)展示主流防挡脸弹幕实现原理点播up上传视频服务器后台计算提取视频画面中的人像区域,转换成svg存储客户端播放视频的同时,从服务器下载svg与弹幕合成,人像

怎么配置nginx保证frps服务器与web共用80端口 怎么配置nginx保证frps服务器与web共用80端口 Jun 03, 2023 am 08:19 AM

首先你会有个疑惑,frp是什么呢?简单的说frp就是内网穿透工具,配置好客户端以后,可以通过服务器来访问内网。现在我的服务器,已经用nginx做站了,80端口只有一个,那如果frp的服务端也想使用80端口,那应该怎么办呢?经过查询,这个是可以实现的,就是利用nginx的反向代理来实现。补充一下:frps就是服务器端(server),frpc就是客户端(client)。第一步:修改服务器中nginx.conf配置文件在nginx.conf中http{}里添加以下参数,server{listen80

web标准是什么东西 web标准是什么东西 Oct 18, 2023 pm 05:24 PM

Web标准是一组由W3C和其他相关组织制定的规范和指南,它包括HTML、CSS、JavaScript、DOM、Web可访问性和性能优化等方面的标准化,通过遵循这些标准,可以提高页面的兼容性、可访问性、可维护性和性能。Web标准的目标是使Web内容能够在不同的平台、浏览器和设备上一致地展示和交互,提供更好的用户体验和开发效率。

如何从驾驶舱Web用户界面启用管理访问 如何从驾驶舱Web用户界面启用管理访问 Mar 20, 2024 pm 06:56 PM

Cockpit是一个面向Linux服务器的基于Web的图形界面。它主要是为了使新用户/专家用户更容易管理Linux服务器。在本文中,我们将讨论Cockpit访问模式以及如何从CockpitWebUI切换Cockpit的管理访问。内容主题:驾驶舱进入模式查找当前驾驶舱访问模式从CockpitWebUI启用Cockpit的管理访问从CockpitWebUI禁用Cockpit的管理访问结论驾驶舱进入模式驾驶舱有两种访问模式:受限访问:这是驾驶舱的默认访问模式。在这种访问模式下,您不能从驾驶舱Web用户

See all articles