html5——文件斷點續傳


  一直以來我都特別好奇,網上很多文件斷點上傳是怎么實現的,像百度雲,最近看到一篇關於HTML5新特性的文章,里面的BLOB對象和FILE對象,有一個slice方法,可以將BLOB對象進行分割。BLOB(Binary Large Object)二進制大對象,屬於XMLHttpRequest2.0中的一員,它的slice方法和字符串和數組的slice方法一樣,用於分割二進制。

  文件上傳后台我是使用php的,上傳的策略是先請求后台詢問上傳的文件是否存在,如果存在則發回已經上傳到哪里。然后前端拿到這個位置,對文件二進制進行分割。

  好,先看看我前端的實現,后台寫得太爛,我就不貼出來了,php的文件主要使用兩個函數,一個是file_put_contents,還有就是file_get_contents

<!DOCTYPE html>
<html>
<head>
    <title>斷點續傳</title>
</head>
<style type="text/css">
    input[type="file" i] {
        width: 100px;
        height: 50px;
        opacity: 0;
        /*visibility: hidden;*/
        margin: 0;
        padding: 0;
        border: 0;
        float: left;
    }
    .upload-button-wrap {
        position: relative;
        display: inline-block;
        vertical-align: middle;
    }
    .upload-button-wrap:hover .upload-button {
        border-color: #000;
    }
    .clearfix:after {
        content: '';
        clear: both;
        display: block;
    }
    .clearfix {
        zoom: 1;
    }
    .upload-button {
        width: 100px;
        height: 50px;
        position: absolute;
        left: 0;
        top: 0;
        z-index: -1;
    }
    .upload-wrap {
        position: relative;
    }
    #uploadButton {
        display: inline-block;
    }
</style>
<body>
    <div class="upload-wrap">
        <div class="upload-button-wrap clearfix">
            <input type="file" id="uploadFile">
            <button class="upload-button">選擇圖片</button>
        </div>
        <button id="uploadButton">上傳</button>
    </div>
<script type="text/javascript">
    (function (w) {
        var fileUpload = function (config) {
            var _files = [],    // 要上傳文件的隊列
                _file = null,    // 當前上傳的文件
                _upload = config.uploadId,    // input[type = "file"]的控件ID
                _submit = config.submitId,    // input[type = "submit"]的控件ID
                _url = config.url,
                _unit = 1024,
                _start = 0,
                _xmlRequest = new XMLHttpRequest();

            var _init = function () {
                document.getElementById(_upload).addEventListener("change", function (e) {
                    _files = this.files;
                    _file = _files[0];
                    e.preventDefault();
                }, false);
                document.getElementById(_submit).addEventListener("click", function (e) {
                    // 向后抬請求文件是否存在
                    _xmlRequest.onload = function () {
                        if (_xmlRequest.readyState == 4 && _xmlRequest.status == 200) {
                            _start = parseInt(_xmlRequest.responseText);
                            _uploadFile();
                        }
                        _xmlRequest.onload = function () {
                            if (_xmlRequest.readyState == 4 && _xmlRequest.status == 200) {
                                if (_xmlRequest.responseText == "success") {
                                    _start = _start + _unit;
                                    _uploadFile();
                                }
                            }
                        }
                    };
                    _getSetbacks();
                    e.preventDefault();
                }, false);
            },
            // 獲取文件進度
            _getSetbacks = function () {
                _xmlRequest.open("GET", _url+"?fileName="+_file.name, true);
                _xmlRequest.send(null);
            },
            // 上傳文件
            _uploadFile = function () {
                if (_start > _file.size) return;
                console.log(_start);
                var formData = new FormData();
                formData.append('fileName', _file.name);
                formData.append('fileContent', _file.slice(_start,_start+_unit));
                _xmlRequest.open("POST", _url, true);
                _xmlRequest.send(formData);
            };

            _init()
        }

        w.fileUpload = fileUpload;

    })(window)
    var f = new fileUpload({
        uploadId: 'uploadFile',
        submitId: 'uploadButton',
        url: './upload.php'
    })
</script>
</body>
</html>

  我先請求后台,通過_getSetback函數獲取文件進度,返回的是已經上傳文件的大小,然后根據文件大小對文件進行切分(slice),最后通過_uploadFile分多次上傳文件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM