zoukankan      html  css  js  c++  java
  • 前端分片上传大文件

    **
    * 分片上传文件类
    */
    export class FragmentUploadFile {
    constructor(options) {
    this.file = options.file; // 文件
    this.url = options.actionUrl; // url
    this.fSize = 5 * 1024 * 1024; // 分片大小 默认为5M,前后端需统一,所以写死就可以了
    this.pause = false; // 是否暂停
    this.chunk = 1; // 当前上传的片
    this.fd = null; // 表单数据
    this.chunks = Math.ceil(options.file.size / this.fSize); // 总的片数
    this._id = random14(); // 14位随机数
    this.userInfo = JSON.parse(sessionStorage.getItem('as_vlink_user_info'));
    this.totalSize = options.file.size; // 文件大小
    this.fileSize = options.file.size / 1024 >= 1000 ? (options.file.size / 1024 / 1024).toFixed(2) + ' M' : (options.file.size / 1024).toFixed(2) + ' KB'
    this.curXhr = null; // 记住当前的xhr,用于随时可暂停
    this.cb = options.cb; // 回调函数
    this.result = {
    mes: "正在计算上传速度...",
    progress: 0,
    fileSize: this.fileSize,
    data: null,
    finishTimeMes: ""
    }
    }

    sendFile() {
    let blobFrom = (this.chunk - 1) * this.fSize,
    blobTo = this.chunk * this.fSize > this.totalSize ? this.totalSize : this.chunk * this.fSize;
    let curSize = 0;
    let startTime = new Date().getTime();
    this.curXhr = new XMLHttpRequest();
    this.curXhr.withCredentials = true;
    this.fd = new FormData();
    this.fd.append("file", this.file.slice(blobFrom, blobTo))
    this.fd.append("fileName", this.file.name);
    this.fd.append("chunk", this.chunk);
    this.fd.append("totalChunks", this.chunks);
    this.fd.append("id", this._id);
    // 当前传的字节数,如果不是最后一片,那么就是fragmentSize
    if (this.chunk * this.fSize > this.totalSize) {
    curSize = this.totalSize - (this.chunk - 1) * this.fSize
    } else {
    curSize = this.fSize;
    }
    this.fd.append("size", curSize)
    this.curXhr.open("post", this.url);
    if (this.userInfo) {
    this.curXhr.setRequestHeader("SESSIONID", this.userInfo.sessionId)
    }
    this.curXhr.send(this.fd);
    this.curXhr.onreadystatechange = () => {
    if (this.curXhr.readyState === 4) {
    if (this.curXhr.status === 200 || this.curXhr.status === 304) {
    this.chunk++;
    // 上传完计算上传速度,如果是最后一片直接显示上传完毕
    if (this.chunk > this.chunks) {
    this.result.mes = "上传完成"
    this.result.data = JSON.parse(this.curXhr.response).data;
    this.result.finishTimeMes = "";
    } else {
    let t = (new Date().getTime() - startTime) / 1000;
    let s = (blobTo - blobFrom) / 1024;
    let speed = s / t >= 1000 ? (s / t / 1024).toFixed(2) + " M/s" : (s / t).toFixed(2) + " KB/S";
    this.result.mes = "上传速度 " + speed;
    let dd = (this.totalSize - blobTo)/ 1024 / (s / t)
    let needTime =
    dd > 3600 ? parseInt(dd / 3600) + " 小时" :
    dd > 60 ? parseInt(dd / 60) + " 分钟" :
    parseInt(dd) + " 秒";
    this.result.finishTimeMes = "预计还需要" + needTime;
    }
    this.result.progress = (100 * blobTo / this.totalSize).toFixed(1) * 1;
    this.cb(this.result);
    if (this.chunk <= this.chunks && !this.pause) {
    this.sendFile();
    }
    }
    }
    }
    }

    /**
    * 暂停上传
    */
    pauseSendFile() {
    this.curXhr && this.curXhr.abort();
    this.pause = true;
    }
    }
  • 相关阅读:
    DotLucene 之 Bugs 小记[转]
    商业搜索引擎都需要哪些技术
    开源搜索引擎资源
    关于笔记本的CPU和显卡性能比较[转]
    上传图片方法大全 [网摘]
    Lucene 中文分词的 highlight 显示
    JS调用服务器端方法
    在线免费图书馆
    用dotLucene为数据库内容建立索引
    mybatis 数据库.xml中方法参考
  • 原文地址:https://www.cnblogs.com/hsdying/p/13235106.html
Copyright © 2011-2022 走看看