Pure Javascript - AJAX File Uploading and Showing Progess Percentage

This tutorial shows how to upload a file using pure or vanilla Javascript. It includes everything that is involved - from selecting a file, validating its type and size, sending an AJAX request and showing the upload progress of the file.

Demo

% uploaded

The demo does not actually send the file to the server, so you will not see the upload progress percentage. However you can download the sample codes present at the end of the tutorial, and implement on your server.

Showing the File Browse Dialog

The file input element <input type="file" /> shows the standard file browse dialog to the user. When this element is clicked, it will allow the user to select a file.

If you are allowing multiple files to be uploaded, add the multiple attribute.

<input type="file" multiple />

You can also restrict what files the user can choose by specifying the required MIME type in the accept attribute (although it is possible for the user to override it). Separate each allowed MIME type by a comma.

<!-- Allow only JPEG & PNG files to choose -->
<input type="file" accept="image/jpeg, image/png" />

Every browser has its own way of displaying the file input element, and it usually looks ugly. For achieving a good user-interface, it is better to hide the file input element and instead show a normal button. When the button is clicked you invoke a click event on the file input element.

<!-- Hide the file input element -->
<input type="file" accept="image/jpg,image/png" style="display:none" id="upload-file" />
<button id="choose-button">Choose Image</button>
// Show the file browse dialog
document.querySelector('#choose-button').addEventListener('click', function() {
	document.querySelector('#upload-file').click();
});

Getting Access to the Chosen Files

The files property of the file input DOM element is an array of file objects representing the files selected by the user.

// Represents the first file selected
document.querySelector('#upload-file').files[0]

// Represents the second file selected
document.querySelector('#upload-file').files[1]

Once the user chooses a file, a change event triggers on the file input element. You can then validate the file type and size.

document.querySelector('#upload-file').addEventListener('change', function() {
	// This is the file user has chosen
	var file = this.files[0];

	// In case of multiple files
	var file2 = this.files[1];
	var file3 = this.files[2];
});

In case you are uploading image files, you can also show a preview of the image. See Previewing Images with jQuery : Data URIs vs Object URLs for more.

Getting the Name of the File & Validating File Type & Size

Using the name property of the file object you can get the name of the file chosen by the user. Usually web applications show the name of the uploaded file in their user interface.

Using the type and size properties, you can validate the type and size of the file. If the user has chosen an incorrect file type or if the file size exceeds your allowed limit, you can show an error message.

document.querySelector('#upload-file').addEventListener('change', function() {
	// This is the file user has chosen
	var file = this.files[0];

	// Allowed types
	var mime_types = [ 'image/jpeg', 'image/png' ];
	
	// Validate MIME type
	if(mime_types.indexOf(file.type) == -1) {
		alert('Error : Incorrect file type');
		return;
	}

	// Max 2 Mb allowed
	if(file.size > 2*1024*1024) {
		alert('Error : Exceeded size 2MB');
		return;
	}

	// Validation is successful
	// This is the name of the file
	alert('You have chosen the file ' + file.name);
});

Sending an AJAX Request

While uploading a file, you need to send a multipart/form-data HTTP POST request to the server. With Javascript this can be achieved using the XMLHttpRequest object.

A FormData object can be send as the POST data. The FormData object automatically sets the Content-Type of the HTTP request, depending on the type of the request data. In case of a file, Content-Type of the HTTP request is set as multipart/form-data.

var data = new FormData();

var request = new XMLHttpRequest();

// File selected by the user
// In case of multiple files append each of them
data.append('file', document.querySelector('#upload-file').files[0]);

// AJAX request finished
request.addEventListener('load', function(e) {
	// request.response will hold the response from the server
	console.log(request.response);
});

// Upload progress on request.upload
request.upload.addEventListener('progress', function(e) {
	var percent_complete = (e.loaded / e.total)*100;
	
	// Percentage of upload completed
	console.log(percent_complete);
});

// If server is sending a JSON response then set JSON response type
request.responseType = 'json';

// Send POST request to the server side script
request.open('post', 'upload.php'); 
request.send(data);

Getting the upload progress : Using the progress event of the upload object of the request, you can get the upload progress as a percentage. You can easily implement a progress bar using this.

Please note that the progress event of the request object will give the download progress (which can be utilized in cases of downloading), while progress event of the upload object of the request will give the upload progress.

Finding AJAX request is completed : Using the load event of the request, you can find whether the request has been completed.

Download Sample Codes

Download

I'm available for freelancing
If you've liked this article, you'll probably like my code too.

From short code snippets to complete web applications, I code in Javascript & PHP
Low Prices from $20, Fast Delivery Time
2 Ways of AJAX File Upload - FormData and FileReader
I'm available for freelancing
If you've liked this article, you'll probably like my code too.

From short code snippets to complete web applications, I code in Javascript & PHP
Low Prices from $20, Fast Delivery Time