简体   繁体   中英

PHP - HTML5 API upload corrupted

Anyone can help me with my code? I wanna build an upload function using HTML5 API. if I upload less than 1mb the file is alright. However, if file more than 1mb the file will be corrupted.

the HTML file :

<!DOCTYPE html>
<html>
    <head>
        <title>Upload</title>
        <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
    </head>
    <body>
        <form method="POST" action="upload.php" enctype='multipart/form-data'>
            <input type="file" name="fileToUpload" id="file"><br />
            <input type="submit" id="submit">
        </form>
    </body>


<script>
    $(document).ready(function(){
        $('#submit').on('click', function(e){
            e.preventDefault();
            sendRequest();
        });

        //window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;

        var bytes_per_chunk = 1048576; // 1mb chunk sizes.
        var global_upload_counter = 0;

        function sendRequest(){
            var blob = document.getElementById('file').files[0];
            var total_size = blob.size;

            var start = 0;
            var end = bytes_per_chunk;
            // var counter = 1;
            while(start < total_size)
            {
                // console.log('start : ' + start + ', end :' + end + ' and counter : ',  counter);
                var chunk = blob.slice(start, end);
                uploadFile(chunk, blob.name);
                start = end;
                end = start + bytes_per_chunk;
                //counter++;
            }

        }

        function uploadFile(chunk, filename){
            var fd = new FormData();
            fd.append('fileToUpload', chunk);

            var xhr = new XMLHttpRequest();

            xhr.addEventListener('load', uploadComplete, false);
            xhr.addEventListener('error', uploadFailed, false);
            xhr.addEventListener('abort', uploadCanceled, false);

            xhr.open('POST', 'upload.php?filename=' + filename);
            xhr.send(fd);

        }

        function uploadComplete(evt) {
            // This event is raised when the server send back a response 
            if (evt.target.responseText != ""){
                alert(evt.target.responseText);
            }
        }

        function uploadFailed(evt) {
            alert("There was an error attempting to upload the file.");
        }

        function uploadCanceled(evt) {
            xhr.abort();
            xhr = null;
        }
    });
    </script>
</html>

PHP code (upload.php):

<?php

$target_path = "upload/";

$tmp_name = $_FILES['fileToUpload']['tmp_name'];
$size = $_FILES['fileToUpload']['size'];
$name = $_FILES['fileToUpload']['name'];
$filename =  $_GET['filename'];

//$target_file = $target_path.$name;

$complete = $target_path. $filename;

// append; open or create binary file for writing at end-of-file
$com = fopen($complete, "ab");
error_log($target_path);

// read as binary
$in = fopen($tmp_name, "rb");
if($in){
    while ($buff = fread($in, $size)){
        fwrite($com, $buff);
    }
}
fclose($in);

First of all, why do you want to separate the file into chunks? You can upload the whole file in a go via AJAX. The error that you are encountering might be due to the chunk logic. Try removing the chunk logic and it will work just fine. So your upload function would look something like this:

$(document).ready(function(){
        $('#submit').on('click', function(e){
            e.preventDefault();
            sendRequest();
        });

        //window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;

        var bytes_per_chunk = 1048576; // 1mb chunk sizes.
        var global_upload_counter = 0;

        function sendRequest(){
            var blob = document.getElementById('file').files[0];
            var total_size = blob.size;

            uploadFile(blob,filename);
        }

        function uploadFile(chunk, filename){
            var fd = new FormData();
            fd.append('fileToUpload', chunk);

            var xhr = new XMLHttpRequest();

            xhr.addEventListener('load', uploadComplete, false);
            xhr.addEventListener('error', uploadFailed, false);
            xhr.addEventListener('abort', uploadCanceled, false);

            xhr.open('POST', 'upload.php?filename=' + filename);
            xhr.send(fd);

        }

        function uploadComplete(evt) {
            // This event is raised when the server send back a response 
            if (evt.target.responseText != ""){
                alert(evt.target.responseText);
            }
        }

        function uploadFailed(evt) {
            alert("There was an error attempting to upload the file.");
        }

        function uploadCanceled(evt) {
            xhr.abort();
            xhr = null;
        }
    });

Instead of chunks, send the full file and it should work. If you are worried about the upload progress, here are a few solutions: jQuery Upload Progress and AJAX file upload , File upload progress bar with jQuery

Looking at the answer provided by user470714 on uploading a file in chunks using html5 I found the issues.

Which the ajax didn't actually uploading the chunks in order. So I updated my HTML code as follow and now it works fine :

<!DOCTYPE html>
<html>
    <head>
        <title>Upload</title>
        <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
    </head>
    <body>
        <form method="POST" action="upload.php" enctype='multipart/form-data'>
            <input type="file" name="fileToUpload" id="file"><br />
            <input type="submit" id="submit">
        </form>
    </body>

<script>
    $(document).ready(function(){
        $('#submit').on('click', function(e){
            e.preventDefault();
            sendRequest();
        });

        //window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;

        var bytes_per_chunk = 1048576; // 1mb chunk sizes.
        var global_upload_counter = 0;


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

            var total_size = blob.size;

            window.upload_counter  = 0;
            window.upload_filearray = [];


            var start = 0;
            var end = bytes_per_chunk;
            while(start < total_size)
            {
                var chunk = blob.slice(start, end);

                window.upload_filearray[window.upload_counter] = chunk;
                window.upload_counter++;

                start = end;
                end = start + bytes_per_chunk;

            }

            // initiate upload the first time
            window.upload_counter = 0;
            window.filename = blob.name;
            uploadFile(window.upload_filearray[window.upload_counter]);

        }


        function uploadFile(chunk){
            var fd = new FormData();
            fd.append('fileToUpload', chunk);

            var xhr = new XMLHttpRequest();

            xhr.addEventListener('load', uploadComplete, false);
            xhr.addEventListener('error', uploadFailed, false);
            xhr.addEventListener('abort', uploadCanceled, false);

            xhr.open('POST', 'upload.php?filename=' + window.filename);

            window.upload_counter++;

            xhr.send(fd);

        }

        function uploadComplete(evt) {
            // This event is raised when the server send back a response 
            if (evt.target.responseText != ""){
                console.log(evt.target.responseText);
            }

            if(window.upload_filearray.length > window.upload_counter){
                uploadFile(window.upload_filearray[window.upload_counter]);
            }
        }

        function uploadFailed(evt) {
            alert("There was an error attempting to upload the file.");
        }

        function uploadCanceled(evt) {
            xhr.abort();
            xhr = null;
        }


    });
    </script>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM