HTML.form.guide

How to upload files via AJAX?

file upload ajax jquery file upload

In Web applications, the common way of uploading files to a web server is through the submission of a form. However, you might come into some scenarios where you might need to upload files via Ajax. This tutorial will show you how.

The following list shows the browser support for Ajax.

  • Opera 7.6 and above.
  • Mozilla Firefox 1.0 and above.
  • Apple Safari 1.2 and above.
  • Netscape version 7.1 and above.
  • Microsoft Internet Explorer 5 and above.
  • Konqueror.

For browser jQuery support, check this page.

Uploading Files via Ajax with jQuery

To follow along with this tutorial, you can download the completed project which contains a simple Node.js application that serves up a webpage, takes uploaded files and saves them to disk. Instructions for running it can be found at the end of this article in the Setting up a Server section.

Here, we'll take a look at the code responsible for the file upload.

If you look at the views/index.html file inside the project folder, you'll see the following markup for a form.

<form>
  <input id="upload_file" type="file" name="upload" multiple="multiple">
</form>

We don't include an action attribute on the form since we don't plan on submitting its data the usual way by using a button or the Return key. We also omit the Submit button since it would be irrelevant here.

The form contains an input field of type file that is used to hold file data. The field contains a multiple="multiple" attribute which enables the user to select multiple files.

Below the form, there is a div with a class of progress. We'll use this to show the progress (in percentage) of the file upload.

<div class="progress"></div>

jQuery is included in the file with the following tag.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

We then have the following code inside another script tag. This is the code that handles the uploading.

$(document).ready(function() {
  $('#upload_file').on('change', function(){
    
    var files = $(this).get(0).files;
    
    if (files.length > 0){
      var formData = new FormData();
      
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        
        formData.append('uploaded_files', file, file.name);
      }
      
      $.ajax({
        url: '/upload',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        success: function(data) {
          alert('Files Saved');
          console.log('Upload Successful!\n' + data);
        },
        error: function(jqXHR, status, error) {
          alert('Upload Failed. Error: ' + error);
        },
        xhr: function() {
          var xhr = new XMLHttpRequest();
          
          xhr.upload.addEventListener('progress', function(event) {
            if (event.lengthComputable) {
              var uploadPercentage = event.loaded / event.total;
              $('.progress').text(parseInt(uploadPercentage * 100) + '%');
            }
            
          }, false);
          
          return xhr;
        }
      });
      
    }
  });
});

We want to upload a user's files the moment they make the selection so we've added an onChange listener on the file input field.

When this listener is called, we first grab the data from the input field and assign it to the files variable.

We then create a FormData object that will be sent in the Ajax request as the data payload.

Next, we iterate through the selected files, adding each one to the FormData.

We then send the data to the server with the jQuery ajax() function. Here we specify the server endpoint the data will be sent to /upload and the type of request that will be made POST.

By default, data that is passed to the data option is processed and transformed into a query string. This is fine for text data, but if you are passing something like files, then you should set processData to false as we've done here. contentType is also set to false because it defaults to application/x-www-form-urlencoded which sends the data as query strings and doesn't send files.

We then set a success callback that will be called if the server request is made successfully, otherwise, the error callback will be called. If the files are successfully uploaded, an alert message is shown to the user letting them know this and a message is outputted to the JavaScript console with details of the uploaded file (if multiple files were selected, each one will be shown as an Object. If you want to see details for all files, check your Terminal.

We also include an xhr callback to keep track of data transfer to and from the server. We instantiate a XMLHttpRequest object and get its upload property. The XMLHttpRequest.upload property returns an XMLHttpRequestUpload object, representing the upload process. Event listeners can then be set on the XMLHttpRequestUpload object to track its process which is what we do in the demo code. Each time the listener is called, we calculate the new progress in percentage and display this value on the web page. Launch the page and try uploading files, you will see a changing percentage value appear below the form (select a considerably large file or several files so the upload takes a bit of time to complete).

Setting up a Server

Download the Server side code here

To run the downloaded code, you'll need to have Node.js installed on your computer.

After unzipping the file download, open Terminal and navigate to the root of the project.

$ cd path/to/node_upload

Install the libraries used by the project with the following command.

$ npm install

Then run the project with:

$ npm start

If everything goes okay, you should see the message Server listening on port 3000 in the Terminal.

On your browser, navigate to http://localhost:3000. You'll see a page with a form containing a single file input field.

When you select files to be uploaded, they will be saved to the /uploads folder found in the project's root directory. After a successful upload, an alert message will be shown with the message Files Saved.

Note that the server we have here is in no way an indication of how you should build a file server. We just wanted to have a simple application that does the job. For your production application, you should ensure that you are doing security checks on the incoming files, you should also consider using a framework like express which comes with features that help building Node applications much more efficiently.