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.