博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于vue的h5文件切片上传(获取文件md5,实现秒传、进度条实现)
阅读量:7112 次
发布时间:2019-06-28

本文共 5022 字,大约阅读时间需要 16 分钟。

hot3.png

template

script

methods: {    file() {        // 模拟点击file input触发选择文件,注意:不能在任何方式的回调里面执行此语句        this.$refs.upload.click()    }    selectFile(event) {        // 调用上传方法,传入选择的文件对象        this.uploadFile(event.target.files[0], () => {            // upload-success        })        // 重置file input控件的值        event.target.value = ''    }}

核心js文件

// uploadFile.jsimport Vue from 'vue'import SparkMD5 from 'spark-md5'export default function() {    // 将上传文件的方法挂载到vue的原型链上面    Vue.prototype.uploadFile = uploadFile    function uploadFile(file, backtopage) {        // 得到md5码        getFileMD5(file, md5 => {            // 存储文件的md5码            file.md5 = md5            // 拿md5码查询后台数据库是否存在此md5码,如果存在则无需上传            // handleAjax为封装好的ajax方法            this.handleAjax('api/doc/file/getFileByMd5', {                md5,                name: file.name            }, res => {                if (!res.data) { // 不存在                    // 开始上传文件                    uploadChunk(this, file, 0, backtopage)                } else { // 秒传                    // 文件上传成功                    backtopage && backtopage()                }            })        })    }    // currentChunk为上传文件块的索引    function uploadChunk(that, file, currentChunk, backtopage) {        var fileReader = new FileReader(),            // 上传文件块的大小,可自定义            chunkSize = 2097152,            // 计算改文件的可分为多少块            chunks = Math.ceil(file.size / chunkSize)        // 文件切割后的回调,this.result为切割的文件块        fileReader.onload = function(e) {            // 用FormData传输文件对象            let fd = new FormData()            // 设置文件上传接口的需要的参数            fd.append('md5', file.md5)            fd.append('chunks', chunks)            fd.append('chunksize', chunksize)            fd.append('currentChunk', currentChunk)            // 设置上传的当前的文件块            fd.append('fileObj', new Blob([this.result]))            let xhr = new XMLHttpRequest()            xhr.open('post', 'api/common/file/upload', true)            xhr.onreadystatechange = function() {                // 上传成功                if (xhr.readyState == 4 && xhr.status == 200) {                    currentChunk++                    if (currentChunk < chunks) {                        loadNext() // 继续切割下一块文件                    } else {                        // 文件上传成功                        backtopage && backtopage()                    }                    xhr = null                    return                }                if (xhr.readyState == 4 && xhr.status == 500) {                    // 文件上传出错                }            }            // 文件上传进度条            xhr.upload.onprogress = function(e) {                // 计算上传的进度                const progress = parseInt((e.loaded + currentChunk * chunkSize) / file.size * 100)                // 更新ui            }            xhr.onerror = xhr.upload.onerror = function() {                // 文件上传出错            }            //开始发送            xhr.send(fd)            fd = null        }        //处理单片文件的上传        function loadNext() {            // 查询后台判断当前块文件有没有上传,如果已经上传则不需要上传,继续读取下一块            that.handleAjax('api/common/file/checkChunk', { md5: upload.md5, chunk: currentChunk }, res => {                // 后台返回没有上传过                if (res.data === false) {                    // 计算切割文件的开始索引和结束索引                    var start = currentChunk * chunkSize,                        end = Math.min(start + chunkSize, file.size)                    // 切割文件并触发fileReader.onload                    fileReader.readAsArrayBuffer(file.slice(start, end))                    // 后台返回此块已经上传过,递归调用loadNext,继续判断下一块文件块                } else {                    currentChunk++                    if (currentChunk < chunks) {                        loadNext()                    }                }            }, err => {                // 文件上传出错            })        }        // 触发文件第一块上传        loadNext()    }    // 获得文件md5    function getFileMD5(file, callback) {        //声明必要的变量        var fileReader = new FileReader(),            //文件每块分割2M,计算分割详情            chunkSize = 2097152,            chunks = Math.ceil(file.size / chunkSize),            currentChunk = 0,            //创建md5对象(基于SparkMD5)            spark = new SparkMD5()        //每块文件读取完毕之后的处理        fileReader.onload = function(e) {            //每块交由sparkMD5进行计算            spark.appendBinary(e.target.result)            currentChunk++            //如果文件处理完成计算MD5,如果还有分片继续处理            if (currentChunk < chunks) {                loadNext()            } else {                callback(spark.end())            }        }        //处理单片文件的上传        function loadNext() {            var start = currentChunk * chunkSize,                end = start + chunkSize >= file.size ? file.size : start + chunkSize            fileReader.readAsBinaryString(file.slice(start, end))        }        loadNext()    }}

将uploadFile.js挂载带vue上面

// main.js// Import Vueimport Vue from 'vue'// Import uploadimport uploadFile from './assets/js/uploadFile'// 把封装好的文件下载挂载到vue上Vue.use(downloadFile)

转载于:https://my.oschina.net/kaikai1/blog/1859976

你可能感兴趣的文章
jQuery介绍
查看>>
[ 转 ] 网页聊天室的原理
查看>>
eclipse中svn提交报错的解决
查看>>
mysql 总结
查看>>
php环境配置和nginx安装配置教程
查看>>
Python学习(21)python操作mysql数据库_操作
查看>>
ASCII
查看>>
TCP/IP协议(数据封装与拆装过程)
查看>>
我的 .npmrc 配置
查看>>
43、转换流
查看>>
ssh端口转发
查看>>
Tomcat.md
查看>>
javascript里用php
查看>>
【BO】SAP BO相关问题汇总贴
查看>>
最短路径(迪杰斯特拉算法)- 数据结构和算法64
查看>>
mac os x查看端口命令
查看>>
位语法
查看>>
redis的两种持久化方案
查看>>
[Python爬虫] 之九:Selenium +phantomjs抓取活动行中会议活动(单线程抓取)
查看>>
ElasticSearch 排序
查看>>