How do old (prior html5) ajax file uploading frameworks work?

121 views Asked by At

Standard html has input element with file type.

Components exist which allow asynchronous file upload with progress reporting.

As far as I understand this can be done by splitting file in chunks and sending multiple requests within 'file upload' session. For this to work JavaScript must have access to file's contents, however I do not know how to do it without FileAPI appeared as part of HTML5.

1

There are 1 answers

0
Jonathan Crowe On BEST ANSWER

Ajax-ish file upload can be achieved in the following way:

1) embed an iframe on your html page (this will be where the actual upload occurs):

<iframe id="upload_target" name="upload_target" src="about:blank" style="position:absolute;width:0;height:0;border:0px solid #fff;"></iframe>

2) set your form target to the iframe:

<form target="upload_target" enctype="multipart/form-data" method="post" action="upload.php">
    <input type="file" name="file" />
</form>

3) handle your upload in upload.php

if(!empty($_FILES['file'])) {
    // upload files
}

4) once upload completes (success or fail) load a view and post a message to the parent window:

<script>
    var files = <?php echo json_encode($files); ?>;
    var errors = <?php echo json_encode($errors); ?>;
    var host = 'http://myhost.com';

    for (var key in files) {
        var message = {
            success : files[key].success,
            fileName : files[key].fileName,
            filePath : files[key].filePath
        };

        if (typeof errors[key] != undefined) {
            message.error = errors[key];
        }

        parent.postMessage(
            JSON.stringify(message), // stringify to work around ie8/9
            host
        );

    }       
</script>

5) receive the response in your original script:

function get_message(cb) {
    cb = cb || function() {};

    handler = handler || function(e) {
        var data = e.data;
        if (typeof data == "string") {
            try {
                data = JSON.parse(data);
            } catch (err) {}
        }

        cb(data, e);
    };


    var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
    var eventer = window[eventMethod];
    var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

    // Listen to message from child window
    eventer(messageEvent, handler, false);
}

get_message(function() {
    if (data.success == true) {
        // file was successfully uploaded
    } else {
        // file was not successfully uploaded
    }
});

This Sitepoint article has a good example of how to track progress (using modern php). It basically involves a lot of pinging to get the latest progress bar, but I have found you can easily fake progress by slowly incrementing your progress bar from 0 - Random number between 50 and 90 and then once you receive the final "success" message pushing it all the way to 100%