• js 大文件分割/分片上传


    <!DOCTYPE html>
    <html>
      <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>uploadFile</title>
        <style></style>
      </head>
      <body>
        <input type="file" id="file" multiple />
        <br />
        <br />
        <button id="btn">上传</button>
    
        <script>
          var uploadFile;
          document.querySelector("#file").addEventListener(
            "change",
            (e) => {
              var files = e.target.files;
              if (!files.length) return;
    
              uploadFile = new CutFileAndUpload({
                files,
                apiUpload: (fileData) => {
                  //接口请求 返回当前文件数据
    
                  /**
                 * fileData = {
                        file: file,  //当前文件
                        succeed: 0, //已经上传的片数
                        shardSize: this.size, //以2MB为一个分片
                        shardCount: 0, //总片数
                        start: 0,  //截取开始位置
                        end: 0,  //截取结束位置
                    }
                */
    
                  //构造一个表单 表单字段根据后端接口而定
                  let fdata = new FormData();
                  //计算切割文件单个分片
                  let base64 = fileData.file.slice(fileData.start, fileData.end);
                  // fdata.append("base64", base64, fileData.file.name);
                  // fdata.append("name", fileData.file.name);
                  // fdata.append("total", fileData.shardCount); //总片数
                  // fdata.append("numbers", fileData.succeed + 1); //当前是第几片
    
                  //接口请求
                  setTimeout(() => {
                    //更新文件数据
                    uploadFile.updateFileData();
                  }, 2000);
                },
                progress: (progress, total) => {
                  //progress 当前文件进度百分比
                  //total 总进度百分比
                  console.log(progress, total);
                },
                success: () => {
                  //上传成功回调
                  console.log("全部上传完成");
                  e.target.value = "";
                },
              });
            },
            false
          );
          document.querySelector("#btn").addEventListener(
            "click",
            () => {
              uploadFile.uploadFile();
            },
            false
          );
    
          /**
           *
           * @param {*} options
           */
          function CutFileAndUpload(options) {
            this.files = options.files || []; //要上传的文件列表
            this.progress = options.progress; //上传进度
            this.success = options.success; //成功回调
            this.apiUpload = options.apiUpload;
    
            this.fileArr = []; //文件列表切割后的文件数据
            this.fileIndex = 0; //上传到第几个文件
            this.size = 2 * 1024 * 1024; //分片单位 以2MB为一个分片
            this.uploading = false; //上传状态
    
            this.cutFile();
          }
          CutFileAndUpload.prototype = {
            constructor: CutFileAndUpload,
            cutFile() {
              var files = this.files;
    
              if (!files.length) {
                console.log("请选择要上传的文件");
                return;
              }
    
              for (var i = 0; i < files.length; i++) {
                var file = files[i];
                let fileData = {
                  file: file,
                  succeed: 0, //已经上传的片数
                  shardSize: this.size, //分片单位
                  shardCount: 0, //总片数
                  start: 0, //截取开始位置
                  end: 0, //截取结束位置
                };
                fileData.shardCount = Math.ceil(
                  fileData.file.size / fileData.shardSize
                ); //总片数
                this.fileArr.push(fileData);
              }
            },
            uploadFile() {
              if (!this.fileArr.length) {
                console.log("请选择要上传的文件");
                return;
              }
    
              var fileData = this.fileArr[this.fileIndex];
              //计算每一片的起始与结束位置
              fileData.start = fileData.succeed * fileData.shardSize;
              fileData.end = Math.min(
                fileData.file.size,
                fileData.start + fileData.shardSize
              );
    
              //计算文件单个分片
              // let base64 = fileData.file.slice(fileData.start, fileData.end);
              // console.log(fileData);
    
              this.uploading = true;
    
              //接口请求
              this.apiUpload && this.apiUpload(fileData);
            },
            updateFileData() {
              //更新文件数据
              var fileData = this.fileArr[this.fileIndex];
              fileData.succeed++;
              var progress = parseInt(
                (fileData.succeed / fileData.shardCount) * 100
              );
              var total;
    
              if (fileData.succeed === fileData.shardCount) {
                //单个文件上传完成
                this.fileIndex++;
                total = parseInt((this.fileIndex / this.fileArr.length) * 100);
                this.progress && this.progress(progress, total);
                if (this.fileIndex == this.fileArr.length) {
                  //列表的全部文件上传完成
                  this.uploading = false;
                  this.fileIndex = 0;
                  this.fileArr = [];
                  this.success && this.success();
                } else {
                  this.uploadFile();
                }
              } else {
                total = parseInt((this.fileIndex / this.fileArr.length) * 100);
                this.progress && this.progress(progress, total);
                this.uploadFile();
              }
            },
          };
        </script>
      </body>
    </html>
  • 相关阅读:
    详细聊聊k8s deployment的滚动更新(一)
    更新k8s镜像版本的三种方式
    深入理解docker信号机制以及dumb-init的使用
    10分钟教你理解反射
    nodejs的交互式解释器模式常用命令
    nrm的安装和使用
    复杂sql语句之单字段分类count计数和多字段count计数
    navicat连接mysql出现2059
    mongodb常规操作语句
    System.Web.NullPointerException
  • 原文地址:https://www.cnblogs.com/haqiao/p/16174613.html
Copyright © 2020-2023  润新知