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分多次上传文件。

原文地址:https://www.cnblogs.com/empty-run/p/5875091.html