Categories

AJAX File Upload

Posted on: October 3, 2015 by Dimitar Ivanov

In a previous post I've described how to upload files asynchronously on cross domains using jQuery and Upload plugin. In this article I will discuss 3 more approaches supported by modern browsers for ajax file upload using raw javascript.

Preparation

Sending form data to a server is accomplished by the XMLHttpRequest Interface. For later use and more convenience let's define a function for sending AJAX requests.

<script>
var ajaxFileUpload = function (data) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "ajax-upload.php", true);
    xhr.addEventListener("load", function (e) {
        // file upload is complete
        console.log(xhr.responseText);
    });
    xhr.send(data);
};
</script>

Ensure that the browser supports HTML5 File API before attempt to reading a file.

<script>
if (window.File && window.FileList && window.Blob && window.FileReader && window.FormData) {
    // proceed with file upload
} else {
    // browser doesn't supports File API
}
</script>

To read a file, stored at the user computer or transferred via Drag & Drop, use the following approaches:

Reading a file with FormData API

  • HTML form - In this case a standard HTML form element already exists in the web page. Giving a form reference to the FormData() constructor creates a new FormData object, that's all we need to perform prior the sending of data to server. Much the same like the AJAX Form submit technique.
<form action="" method="post">
    <input type="text" name="user_name" />
    <input type="file" name="user_file" />
    <button type="submit">Submit</button>
</form>

<script>
var form = document.querySelector("form");

form.addEventListener("submit", function (e) {
    var fdata = new FormData(this);

    // Optional. Append custom data.
    fdata.append('user_city', 'Los Angeles');

    ajaxFileUpload(fdata);

    // Prevents the standard submit event
    e.preventDefault();
    return false;
}, false);
</script>
  • Programmatically - Having a HTML form is not necessary to upload a file. Just create a FormData object and manually adjust its elements using the .append() and/or .set() methods.
<script>
var fdata = new FormData();
fdata.append("user_name", "Dimitar Ivanov");
fdata.append("user_file", "/path/to/file.png");
// Overwrite the value of 'user_file' key
fdata.set("user_file", "/path/to/cv.pdf", "Dimitar-CV.pdf");

ajaxFileUpload(fdata);
</script>

Reading a file with FileList API

All HTML <input> elements have an files array on them accessed via the files property. This array contains a list of files selected with <input type="file"> element.

<form action="" method="post">
    <input type="text" name="nickname" />
    <input type="file" name="cv" />
    <input type="file" name="avatar" />
    <button type="submit">Submit</button>
</form>

<script>
var input = document.querySelector('input[type="file"]');
var fdata = new FormData();
var file;
for (var i = 0, iCnt = input.files.length; i += 1) {
    file = input.files[i];
    // or using the .item() method, it's the same
    // file = input.files.item(i);
    fdata.append(file.name, file);
}

// Optional. Append custom data.
fdata.append("sex", "male");

ajaxFileUpload(fdata);
</script>

Reading a file with FileReader API

Web apps are able to read the content of files with using the FileReader API.

<script>
var ajaxFileUpload = function (file) {
    var reader = new FileReader()
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "ajax-upload.php", true);
    xhr.addEventListener("load", function (e) {
        // file upload is complete
        console.log(xhr.responseText);
    });
    reader.addEventListener("load", function (e) {
        xhr.sendAsBinary(e.target.result);
    });
    reader.readAsBinaryString(file);
};

ajaxFileUpload('https://static.zinoui.com/img/blog/ajax-file-upload.png');
</script>
Summary

If you have any thoughts about the discussed approaches for ajax file upload, please post a comment below.

Thanks so much for reading!

Make your website more secure by using the HTTP Headers for Wordpress, and never face a cross-origin issue again. Oh yes, it's FREE.
See also
References
Share this post

0 Comments

Comments are closed