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.