html5大文件上传

html端将文件进行切割,提交给upload.php1upload.php将上传的文件片移到文件夹临时存放.当最后一块文件片成功提交到upload.php后,向merge.php提交一个合并文件片的请求。

html:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>大文件上传实例</title>
    <script type="text/javascript">
        const BYTES_PER_CHUNK = 1024 * 1024; // 每个文件切片大小定为1MB .
        var slices;
        var totalSlices;

        //发送请求
        function sendRequest() {

            var blob = document.getElementById('file').files[0];

            var start = 0;
            var end;
            var index = 0;

            // 计算文件切片总数
            slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
            totalSlices= slices;

            while(start < blob.size) {
                end = start + BYTES_PER_CHUNK;
                if(end > blob.size) {
                    end = blob.size;
                }

                uploadFile(blob, index, start, end);

                start = end;
                index++;
            }
        }

        //上传文件
        function uploadFile(blob, index, start, end) {
            var xhr;
            var fd;
            var chunk;

            xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4) {
                    if(xhr.responseText) {
                        alert(xhr.responseText);
                    }

                    slices--;

                    // 如果所有文件切片都成功发送,发送文件合并请求。
                    if(slices == 0) {
                        mergeFile(blob);
                        alert('文件上传完毕');
                    }
                }
            };


            chunk =blob.slice(start,end);//切割文件

            //构造form数据
            fd = new FormData();
            fd.append("file", chunk);
            fd.append("name", blob.name);
            fd.append("index", index);

            xhr.open("POST", "upload.php", true);

            //设置二进制文边界件头
            xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
            xhr.send(fd);
        }

        function mergeFile(blob) {
            var xhr;
            var fd;

            xhr = new XMLHttpRequest();

            fd = new FormData();
            fd.append("name", blob.name);
            fd.append("index", totalSlices);

            xhr.open("POST", "merge.php", true);
            xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
            xhr.send(fd);
        }

    </script>
</head>
<body>

<input type="file" id="file"/>
<button  onclick="sendRequest()">上传</button>
</body>
</html>

upload.php:

<?php
//省略了文件接收判断isset部分
//当前目录下建立一个uploads文件夹
//接收文件名时进行转码,防止中文乱码。
$target = "uploads/" .iconv("utf-8","gbk",$_POST["name"]) . '-' . $_POST['index'];
move_uploaded_file($_FILES['file']['tmp_name'], $target);

// Might execute too quickly.
sleep(1);


merge.php:

<?php
//文件合并
$target = "uploads/" .iconv("utf-8","gbk",$_POST["name"]);
$dst = fopen($target, 'wb');

for($i = 0; $i < $_POST['index']; $i++) {
    $slice = $target . '-' . $i;
    $src = fopen($slice, 'rb');
    stream_copy_to_stream($src, $dst);
    fclose($src);
    unlink($slice);
}

fclose($dst);

发表评论

邮箱地址不会被公开。 必填项已用*标注