IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue中实现分片大文件上传 -> 正文阅读

[JavaScript知识库]vue中实现分片大文件上传

一、安装? spark-md5

npm i spark-md5 --save

二、上传大文件组件(全代码)复制粘贴就能用

<template>
    <div class="myDiv">
        <el-upload class="upload-demo" action="#" :on-change="uploadFile" :show-file-list="true" :file-list="fileList" :auto-upload="false" ref="uploadfile" :limit="1">
            <el-button size="small" type="primary" :loading="loadingFile">上传文件</el-button>
        </el-upload>
    </div>
</template>

<script>
import SparkMD5 from "spark-md5";
const chunkSize = 10 * 1024 * 1024;//定义分片的大小 暂定为10M,方便测试
import { message_s, message_w } from '@/methods/element';//引入elementui消息提示框
export default {
    name: '',
    components: {},
    props: {},
    data() {
        return {
            fileList: [],
            loadingFile: false
        }
    },
    watch: {},
    computed: {},
    methods: {
        /**
         * 上传文件
         */
        async uploadFile(File) {
            this.loadingFile = true
            var self = this
            //获取用户选择的文件
            const file = File.raw
            this.currentFile = file
            //文件大小(大于100m再分片哦,否则直接走普通文件上传的逻辑就可以了,这里只实现分片上传逻辑)
            const fileSize = File.size
            // 放入文件列表
            this.fileList = [{ "name": File.name }]
            // 可以设置大于多少兆可以分片上传,否则走普通上传
            if (fileSize <= chunkSize) {
                console.log("上传的文件大于10m才能分片上传")
            }
            //计算当前选择文件需要的分片数量
            const chunkCount = Math.ceil(fileSize / chunkSize)
            console.log("文件大小:", (File.size / 1024 / 1024) + "Mb", "分片数:", chunkCount)
            //获取文件md5
            const fileMd5 = await this.getFileMd5(file, chunkCount);
            console.log("文件md5:", fileMd5)

            console.log("向后端请求本次分片上传初始化")

            const initUploadParams = {
                "identifier": fileMd5, //文件的md5
                "filename": File.name, //文件名
                "totalChunks": chunkCount, //分片的总数量
            }
            // 调用后端检查文件上传情况接口
            this.service("/upload/checkChunkExist", 'post', initUploadParams, async (res) => {
                //分片上传成功且未合并,那就调用合并接口
                if (res.data.allUploadSuccess === true && res.data.mergeSuccess == false) {
                    console.log("当前文件上传情况:所有分片已在之前上传完成,仅需合并")
                    self.composeFile(fileMd5, File.name, chunkCount)
                    self.storeBucket = ""
                    self.loadingFile = false
                    return false;
                }
                // 所有分片上传成功且合并成功,直接秒传
                if (res.data.allUploadSuccess === true && res.data.mergeSuccess === true) {
                    console.log("当前文件上传情况:秒传")
                    self.loadingFile = false
                    message_s("上传成功")
                    self.fileList = []
                    self.$refs.upload.clearFiles()
                    return false;
                }
                // 获取后端返回的已上传分片数字的数组
                var uploaded = res.data.uploaded
                // 定义分片开始上传的序号
                // 由于是顺序上传,可以判断后端返回的分片数组的长度,为0则说明文件是第一次上传,分片开始序号从0开始
                // 如果分片数组的长度不为0,我们取最后一个序号作为开始序号
                var num = uploaded.length == 0 ? 0 : uploaded[uploaded.length - 1]
                console.log(num, '分片开始序号')
                // 当前为顺序上传方式,若要测试并发上传,请将103 行 await 修饰符删除即可
                // 循环调用上传
                for (var i = num; i < chunkCount; i++) {
                    //分片开始位置
                    let start = i * chunkSize
                    //分片结束位置
                    let end = Math.min(fileSize, start + chunkSize)
                    //取文件指定范围内的byte,从而得到分片数据
                    console.log(File, '0000')
                    let _chunkFile = File.raw.slice(start, end)
                    console.log(_chunkFile)
                    console.log("开始上传第" + i + "个分片")
                    let formdata = new FormData()
                    formdata.append('identifier', fileMd5)
                    formdata.append('filename', File.name)
                    formdata.append('totalChunks', chunkCount)
                    formdata.append('chunkNumber', i)
                    formdata.append('totalSize', fileSize)
                    formdata.append('file', _chunkFile)

                    // 通过await实现顺序上传
                    await this.getMethods(formdata)
                }
                // 文件上传完毕,请求后端合并文件并传入参数
                self.composeFile(fileMd5, File.name, chunkCount)
            })
        },
        /**
         * 上传文件方法
         * @param formdata 上传文件的参数
         */
        getMethods(formdata) {
            return new Promise((resolve, reject) => {
                this.service("/upload/chunk", 'post', formdata, (res) => {
                    console.log(res)
                    resolve();
                })
            });
        },
        /**
      * 获取文件MD5
      * @param file
      * @returns {Promise<unknown>}
      */
        getFileMd5(file, chunkCount) {
            return new Promise((resolve, reject) => {
                let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
                let chunks = chunkCount;
                let currentChunk = 0;
                let spark = new SparkMD5.ArrayBuffer();
                let fileReader = new FileReader();

                fileReader.onload = function (e) {
                    spark.append(e.target.result);
                    currentChunk++;
                    if (currentChunk < chunks) {
                        loadNext();
                    } else {
                        let md5 = spark.end();
                        resolve(md5);
                    }
                };
                fileReader.onerror = function (e) {
                    reject(e);
                };
                function loadNext() {
                    let start = currentChunk * chunkSize;
                    let end = start + chunkSize;
                    if (end > file.size) {
                        end = file.size;
                    }
                    fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
                }
                loadNext();
            });
        },
        /**
         * 请求后端合并文件
         * @param fileMd5 文件md5
         * @param fileName 文件名称
         * @param count 文件分片总数
         */
        composeFile(fileMd5, fileName, count) {
            console.log("开始请求后端合并文件")
            var data = {
                "identifier": fileMd5, //文件的md5
                "filename": fileName, //文件名
                "totalChunks": count //分片的总数量
            }
            this.service('/upload/merge', 'post', data, (data) => {
                if (data.successful == true) {
                    message_s(data.message)
                    this.loadingFile = false
                    this.$refs.upload.clearFiles()
                } else {
                    this.loadingFile = false
                    message_w(data.message)
                }
            })
        },
    },
    created() { },
    mounted() { }
}
</script>
<style lang="less" scoped>
</style>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 12:02:02  更:2022-04-29 12:04:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:48:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码