美文网首页
JS分片上传

JS分片上传

作者: 隐形的稻草人_44ca | 来源:发表于2018-12-28 14:44 被阅读0次

JS分片上传

//分片上传

function ScarecrowPatchUpload (uploadPath, isPatch,onePackSize=1024*1024) {

    //是否分片上传

    isPatch = isPatch == undefined ? false : Boolean(isPatch);

    if (uploadPath == undefined) {

        throw new Error("ScarecrowPatchUpload obj must parameter 1:uploadPath");

    }

    this.__init__(uploadPath, isPatch, onePackSize);

}

ScarecrowPatchUpload.prototype={

    constructor: ScarecrowPatchUpload,

    fileObj:null,

    fileName:"",

    fileSize:0,

    uploadPath:"./",

    onePackSize:1024*1024*8,

    blockData:null,

    blockNum:0,

    blockNumSum:0,

    isPatch:false,

    startIndex:0,

    endIndex:0,

    formData:null,

    ajaxObj:null,

    isSend:false,

    isSendTemp:true,

    __iCnt:0,

    //上传完成回调函数

    funcUploadSuccess:function () {},

    //每个分片上传成功回调函数

    funcUploadStateChange:function () {},

    __init__:function (uploadPath, isPatch, onePackSize) {

        this.isPatch = isPatch;

        this.formData = new FormData();

        this.ajaxObj = new XMLHttpRequest();

        this.uploadPath = uploadPath;

        if (this.isPatch) {

            this.onePackSize = onePackSize;

        }

    },

    addFile:function (fileInfo) {

        if (fileInfo.files.length < 1) {

            console.error("没有找到对应的文件");

            return false;

        }

        console.log(fileInfo.files);

        this.fileObj = fileInfo.files[0];

        this.fileName = this.fileObj.name;

        this.fileSize = this.fileObj.size;

        if (this.isPatch) {

            this.blockNumSum = Math.ceil(this.fileSize / this.onePackSize)

        }

        this.isSend = true;

        this.isSendTemp = false;

        if (this.isPatch) {

            this.__iCnt = setInterval(()=>{

                console.log(this.blockNum);

                if (this.blockNum >= this.blockNumSum) {

                    clearInterval(this.__iCnt);

                    return ;

                }

                if (this.isSendTemp) {

                    this.sendFile();

                }

            }, 500);

        }

    },

    //发送文件

    sendFile:function () {

        this.isSendTemp = false;

        if (!this.isSend) {

            console.error("请先使用addFile添加文件对象");

            return false;

        }

        if (this.isPatch) {

            if(!this.cutFile()){

                return ;

            }

        } else {

            this.blockNum = 1;

            this.blockNumSum = 1;

            this.blockData = this.fileObj;

        }

        this.clearFormData();

        this.formData.append('file', this.blockData);

        this.formData.append('blockNum', this.blockNum);

        this.formData.append('blockNumSum', this.blockNumSum);

        this.formData.append('fileName', this.fileName);

        this.formData.append('isPatch', this.isPatch);

        this.ajaxObj.open('POST',this.uploadPath,false);

        this.ajaxObj.onreadystatechange =  () => {

            if (this.ajaxObj.status == 500 && this.isPatch) {

                clearInterval(this.__iCnt);

            }

            if (this.ajaxObj.readyState == 4 && this.ajaxObj.status == 200) {

                this.funcUploadStateChange.call(this);

                if (this.blockNum >= this.blockNumSum) {

                    this.funcUploadSuccess.call(this);

                    this.__resetObj();

                }

                this.ajaxObj.readyState = 1;

                this.isSendTemp = true;

            }

        }

        this.ajaxObj.send(this.formData);

    },

    //分割文件

    cutFile:function () {

        this.endIndex = this.startIndex + this.onePackSize;

        if (this.startIndex > this.fileSize) {

            this.startIndex = 0;

            return false;

        }

        this.blockNum += 1;

        this.blockData = this.fileObj.slice(this.startIndex, this.endIndex);

        this.startIndex = this.endIndex;

        return true;

    },

    clearFormData:function () {

        this.formData.has('file') ? this.formData.delete("file"): null;

        this.formData.has('blockNum') ? this.formData.delete("blockNum"): null;

        this.formData.has('blockNumSum') ? this.formData.delete("blockNumSum"): null;

        this.formData.has('fileName') ? this.formData.delete("fileName"): null;

        this.formData.has('isPatch') ? this.formData.delete("isPatch"): null;

    },

    setFuncUploadSuccess:function (func) {

        if (typeof func == "function") {

            this.funcUploadSuccess = func;

        } else {

            throw new Error("setFuncUploadSuccess parameter 1 must is function");

        }

    },

    //设置上传状态改变函数

    setFuncUploadStateChange:function (func) {

        if (typeof func == "function") {

            this.funcUploadStateChange = func;

        } else {

            throw new Error("setFuncUploadStateChange parameter 1 must is function");

        }

    },

    //重置参数

    __resetObj:function () {

        this.fileObj = null;

        this.blockNumSum = 0;

        this.blockNum = 0;

        this.endIndex = 0;

        this.formData = new FormData();

    }

}


文档:

## 分页上传JS说明文档

## 方法:

### addFile(fileInfo):void

    添加一个文件对象

    fileInfo为input 中的file具体对象

### sendFile():void

    上传文件

### setFuncUploadSuccess(func):void

    设置上传成功后的回调函数

    func:callback 回调函数

### setFuncUploadStateChange(func):void

    设置分片上传每个分片上传成功时的回调函数

    func:callback 回调函数   


示例:

index.html

<!doctype html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport"

          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

    <style>

        #progress{

            width: 300px;

            height: 20px;

            background-color:#f7f7f7;

            box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);

            border-radius:4px;

            background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);

        }

        #finish{

            background-color: #149bdf;

            background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);

            background-size:40px 40px;

            height: 100%;

        }

        form{

            margin-top: 50px;

        }

    </style>

</head>

<body>

<div id="progress">

    <div id="finish" style="width: 0%;" progress="0"></div>

    <br>

    <span id="showjindu"></span>

</div>

<form>

    <input type="file" name="file" id="file">

    <input type="button" value="上传" id="sc">

</form>

<script src="ScarecrowPatchUpload.js"></script>

<script>

    var fileForm = document.getElementById("file");

    upload = new ScarecrowPatchUpload("./index.php", true);

    upload.setFuncUploadSuccess(function () {

        console.log(this.fileName+"上传成功");

        alert(this.fileName+"上传成功");

    });

    upload.setFuncUploadStateChange(function () {

        var progress;

        var progressObj = document.getElementById('finish');

        var showjindu = document.getElementById("showjindu");

        if(this.blockNumSum == 1){

            progress = '100%';

        }else{

            progress = Math.min(100,(this.blockNum/this.blockNumSum)* 100 ) +'%';

        }

        progressObj.style.width = progress;

        showjindu.innerHTML= progress;

    });

    fileForm.onchange = function(){

        upload.addFile(this);

        upload.sendFile();

    }

</script>

</body>

</html>


upload.php

<?php

class Upload{

    private $filepath = './upload'; //上传目录

    private $tmpPath; //PHP文件临时目录

    private $blobNum; //第几个文件块

    private $totalBlobNum; //文件块总数

    private $fileName; //文件名

    public function __construct($tmpPath,$blobNum,$totalBlobNum,$fileName){

        $this->tmpPath = $tmpPath;

        $this->blobNum = $blobNum;

        $this->totalBlobNum = $totalBlobNum;

        $this->fileName = $fileName;

    }

    //判断是否是最后一块,如果是则进行文件合成并且删除文件块

    private function fileMerge(){

        if($this->blobNum == $this->totalBlobNum){

            $file = fopen($this->filepath.'/'. $this->fileName, "a+");

            $blob = '';

            for($i=1; $i<= $this->totalBlobNum; $i++){

                $blob = file_get_contents($this->filepath.'/'. $this->fileName.'__'.$i);

                fwrite($file, $blob);

            }

            fclose($file);

            $this->deleteFileBlob();

        }

    }

    //删除文件块

    private function deleteFileBlob(){

        for($i=1; $i<= $this->totalBlobNum; $i++){

            @unlink($this->filepath.'/'. $this->fileName.'__'.$i);

        }

    }

    //移动文件

    private function moveFile(){

        $this->touchDir();

        $filename = $this->filepath.'/'. $this->fileName.'__'.$this->blobNum;

        if (is_uploaded_file($this->tmpPath)){

            move_uploaded_file($this->tmpPath,$filename);

        }

    }

    //建立上传文件夹

    private function touchDir(){

        if(!file_exists($this->filepath)){

            return mkdir($this->filepath);

        }

    }

    //开始接受上传

    public function start()

    {

        $this->moveFile();

        $this->fileMerge();

    }

}

//实例化并获取系统变量传参

$upload = new Upload($_FILES['file']['tmp_name'],$_POST['blockNum'],$_POST['blockNumSum'],$_POST['fileName']);

$upload->start();

相关文章

  • JS分片上传

    JS分片上传 //分片上传 function ScarecrowPatchUpload (uploadPath, ...

  • js文件分片上传

    知识点:File,Blob,FileReader,hash,promisify,async, await 文件Fi...

  • 文件分片上传.md

    文件分片上传 文件分片上传的总体思路是 先将文件通过blob.slice()方法将文件切割成多个分片。然后循环上传...

  • webuploader前端分片上传

    前端分片上传附件 分片上传定义: 所谓的分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块...

  • 阿里oss文件分片上传

    OSS文件分片上传 依赖 基础参数dto 具体上传方法 小文件上传 大文件上传,分片oss自己处理 处理逻辑:前段...

  • 七牛云上传及上传方法封装

    分片及七牛云上传封装项目里面用到七牛云,有分片和简单上传 在此做下简单的记录,分享 下面是分片上传封装 proce...

  • js分片上传&断点续传

    原理 js将大文件分成多分,全部上传成功之后,调用合并接口合成文件。如果传输中断,下次上传的时候过滤掉已经上传成功...

  • 分块上传预签名Demo

    分块上传预签名Demo 以下是分块上传的两个步骤 初始化分片上传 获取上传分片的预签名URL 使用该URL可以不带...

  • js+php大文件分片上传

    前端部分 后端部分php

  • js分片

网友评论

      本文标题:JS分片上传

      本文链接:https://www.haomeiwen.com/subject/ezgslqtx.html