html5 文件上傳

html5文件上傳

概念

分片

推薦的分塊大小是2M-5M,具體size根據產品中文件上傳的大小分佈來定。若是上傳的文件大部分是500M以上,很大的文件,建議是5M, 若是相對較小,推薦2M。javascript

斷點續傳

好處

  1. 節省流量,避免上傳重複的分塊。php

  2. 減小用戶等待時間。css

  3. 可恢復的上傳。出現中斷,就算瀏覽器刷新或者是換了臺電腦也能恢復到上次中斷的位置。html

核心代碼

如下代碼上傳音頻有點問題,上傳進度沒有作,往後閒時補上。html5

javascript

(function ($, global, doc) {
    var form = doc.forms["upload"];

    // Upload類
    function Upload (file) {
        this.file = file;
        this.fileInfo = {
            fileName: this.file.name,
            fileType: this.file.type,
            fileSize: this.file.size
        };

        this.reader = new FileReader();
        // 開始讀取指定的Blob對象或File對象中的內容. 當讀取操做完成時,readyState屬性的值會成爲DONE,若是設置了onloadend事件處理程序,則調用之.同時,result屬性中將包含所讀取文件的原始二進制數據.
        this.reader.readAsBinaryString(this.file);

        // 塊大小默認爲4MB
        this.opts = {
            chunkSize: 4 * 1024 * 1024,
            chunkIndex: 0
        };
        $.extend(this.opts, {
            chunkCount: Math.ceil(this.fileInfo.fileSize / this.opts.chunkSize)
        });

        this.bindEvent();

        return this;
    };
    Upload.prototype = {
        bindEvent: function () {
            var self = this;

            self.reader.onloadstart = function () {
                self.uploadChunk();
            };

            return self;
        },
        uploadFinish: function (data) {
            var self = this;
            var previewStr = '';

            switch (self.fileInfo.fileType.substring(0, self.fileInfo.fileType.indexOf('/'))) {
                case 'image':
                                previewStr = '<img src="' + ('upload/' + data.url) + '">';
                                $('.preview').html(previewStr);
                                break;
                case 'audio':
                                previewStr = '<audio src="' + ('upload/' + data.url) + '" controls="controls"></audio>';
                                break;

                default:
                                $('.preview').html(previewStr);
            }

            return self;
        },
        updateProcess: function () {


            return this;
        },
        uploadChunkAfter: function (data) {
            var self = this;

            self.opts.chunkIndex++;
            if (self.opts.chunkIndex < self.opts.chunkCount) {
                self.uploadChunk();
            } else {
                self.uploadFinish(data);
            }

            updateProcess();

            return self;
        },
        uploadChunk: function () {
            var fData = new FormData();
            var self = this;

            fData.append("file", self.file.slice(self.opts.chunkIndex * self.opts.chunkSize, self.opts.chunkSize * (self.opts.chunkIndex + 1)));
            fData.append("fileName", self.fileInfo.fileName);
            fData.append("fileSize", self.fileInfo.fileSize);
            fData.append("fileType", self.fileInfo.fileType);
            fData.append("chunkCount", self.opts.chunkCount);
            fData.append("chunkIndex", self.opts.chunkIndex);
            fData.append("trueName", self.fileInfo.fileName.substring(0, self.fileInfo.fileName.lastIndexOf('.')));
            $.ajax({
                url: 'controller/upload.php',
                type: 'POST',
                data: fData,
                processData: false,
                contentType: false,
                cache: false,
                dataType: "json",
                success: function (data) {
                    self.uploadChunkAfter(data);
                }
            });

            return self;
        },
        util: function () {
            return {
                // 字節轉換成對應的單位
                bytesTosize: function (data) {
                    var unit = ["Bytes", "KB", "MB", "GB"];
                    var i = parseInt(Math.log(data) / Math.log(1024));
                    return (data / Math.pow(1024, i)).toFixed(1) + " " + unit[i];
                },
                // 秒轉換成對應的時間
                secondsTotime: function (sec) {
                    var h = Math.floor(sec / 3600),
                        m = Math.floor((sec - h * 3600) / 60),
                        s = Math.floor(sec - h * 3600 - m * 60);
                    if(h < 10) h = "0" + h;
                    if(m < 10) m = "0" + m;
                    if(s < 10) s = "0" + s;

                    return h + ":" + m + ":" + s;
                }
            }
        }
    };

    $('#submit').on('click', function () {
        var File = new Upload(form["file"].files[0]);

        return false;
    });
})(jQuery, window, document);

html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>分塊上傳</title>
</head>
<body>
    <form name="upload" action="" enctype="multipart/form-data" method="post">
        <input type="file" id="file" name="file">
        <input type="button" id="submit" value="提交">
    </form>
    <div class="preview"></div>
    <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
    <script src="js/upload.js"></script>
</body>
</html>

php

<?php
    $fsize = $_POST['fileSize'];
    $findex =$_POST['chunkIndex'];
    $ftotal =$_POST['chunkCount'];
    $ftype = $_POST['fileType'];
    $fdata = $_FILES['file'];
    $fname = mb_convert_encoding($_POST['fileName'],"gbk","utf-8");
    $truename = mb_convert_encoding($_POST['trueName'],"gbk","utf-8");

    $path = "../";
    $dir = $path."upload/".$truename."-".$fsize;
    $save = $dir."/".$fname;
    if(!is_dir($dir))
    {
        mkdir($dir);
        chmod($dir,0777);
    }

    //讀取臨時文件內容
    $temp = fopen($fdata["tmp_name"],"r+");
    $filedata = fread($temp,filesize($fdata["tmp_name"]));

    //將分段內容存放到新建的臨時文件裏面
    if(file_exists($dir."/".$findex.".tmp")) unlink($dir."/".$findex.".tmp");
    $tempFile = fopen($dir."/".$findex.".tmp","w+");
    fwrite($tempFile,$filedata);
    fclose($tempFile);

    fclose($temp);

    if($findex+1 == $ftotal)
    {
        if(file_exists($save)) @unlink($save);
        //循環讀取臨時文件並將其合併置入新文件裏面
        for($i=0;$i<$ftotal;$i++)
        {
            $readData = fopen($dir."/".$i.".tmp","r+");
            $writeData = fread($readData,filesize($dir."/".$i.".tmp"));

            $newFile = fopen($save,"a+");
            fwrite($newFile,$writeData);
            fclose($newFile);

            fclose($readData);

            $resu = @unlink($dir."/".$i.".tmp");
        }
        $res = array("res"=>"success","url"=>mb_convert_encoding($truename."-".$fsize."/".$fname,'utf-8','gbk'));
        echo json_encode($res);
    }
?>

參考文檔

fexjava

相關文章
相關標籤/搜索