前端实现文件上传及分片上传

相关对象 File Blob FormData FileReader,其中File 对象是 Blob 的子类,所以可以直接使用Blob对象的slice方法,分片操作主要用slice方法实现

<template>
  <div>
    <input type="file" name="file" @change="fileChange" multiple />
    <div>{{ precent }}%</div>
    <span v-for="item in imgList" :key="item">{{ item.name }}</span>
    <img style="width: 200px" :src="imgbase64" />
    <button @click="submit">提交</button>
  </div>
</template>

<script>
import axios from "axios";
import { fstat } from "fs";
let _fileObj;
export default {
  name: "HelloWorld",
  data() {
    return {
      imgbase64: "",
      imgList: [],
      precent: 0,
    };
  },
  methods: {
    fileChange(e) {
      let file = e.target.files[0]; //获取file对象中的第一个文件
      _fileObj = file;
      //如对文件有一定要求可通过形如下列判断
      if (file.size > 10 * 1024 * 1024) {
        alert("文件不能大于十兆");
      }
      if (file.type !== "video/mp4") {
        alert("必须是mp4");
      }
      let _sliceBlob = new Blob([file]).slice(0, 5000); //Blob和File对象第一项必须都是传入一个数组,使用slice方法则可实现分片
      let _sliceFile = new File([_sliceBlob], "test.png"); //File和Blob可以实现对象间的相互转化 File=>Blob或Blob=>File
      let fr = new FileReader();
      fr.readAsDataURL(_sliceFile); //使用FileReader对象的方法将file转为base64
      let self = this; //普通函数内this指向会改变
      fr.onload = function () {
        self.imgbase64 = fr.result;
      };
      //怎么做缩略图,文本预览
      //多文件上传
      if (e.target.files.length > 1) {
        this.imgList.concat(e.target.files);
      } else {
        this.imgList.push(e.target.files[0]);
      }
      //切片上传
      _fileObj = e.target.files[0];
    },
    async submit() {
      this.imgList.forEach((item) => {
        let _formData = new FormData();
        //_formData.append("user", "asdasd");
        _formData.append(item.name + "file", item);
        axios.post("/xx", _formData); //后端一般接受formData对象或者用FileReader转换后的对象
      });
      let size = 2 * 1024 * 1024; //限制每次传2兆
      let fileSize = _fileObj.size; //文件总大小
      let current = 0; //当前是第几兆(传了多少)
      //localStorage.setItem(_fileObj.name, current);  //断点续传
      while (current < fileSize) {
        //如果当前传的大小小于文件总大小则继续
        let _formData = new FormData();
        _formData.append(
          _fileObj.name, //后端根据文件名来合并文件
          _fileObj.slice(current, current + size) //每次分片传哪部分 假如文件有7兆 0-2 2-4 4-6 6-8(即使到7就结束了也不会报错,会完整上传)
        );
        await axios.post("http://localhost:4000/upload", _formData); //一次一次发请求传递给后端
        this.precent = Math.min((current / fileSize) * 100, 100); //当前上传进度
        current += size; //每次加上分片大小
      }
    },
  },
};
// 1,单多文件上传,切片上传,断点续传 2,file blob fileReader formdata
</script>

各对象间的转换关系如下图
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值