Ajax file upload with fetch and FormData

Uploading files using an Ajax request is easier than ever with a couple of fairly recent additional web APIs, fetch and FormData. I’ll show how to combine these two APIs to upload files using an Ajax request.

If you’re like me you probably have heard of fetch. It is basically a nicer API for creating and dealing with XMLHttpRequests. I’ve only briefly encountered FormData until recently when I worked on the file upload for the upcoming Airavata Django portal. FormData provides an interface for adding key/value pairs as would be submitted by a web form, but it can also handle files that the user has selected to upload.

So let’s say you have an <input id="profile-pic" type="file"></input> element in your page and you want to use Ajax to upload the file when selected by the user. You can upload the file like so

let profilePic = document.querySelector('#profile-pic');
let data = new FormData();
data.append('file', profilePic.value);
let uploadRequest = fetch('/profile/picture-upload', {
    method: 'post',
    body: data,
})
    .then(response => response.json())
    // here you would handle success response and error cases

You can also post additional non-file values, just like in an HTML form. So for example you could do the following:

let profilePic = document.querySelector('#profile-pic');
let data = new FormData();
data.append('file', profilePic.value);
data.append('user-id', userId);
let uploadRequest = fetch('/profile/picture-upload', {
    method: 'post',
    body: data,
})
    .then(response => response.json())
    // here you would handle success response and error cases

fetch automatically chooses the right content-type to use when submitting the request based on the kind of data in the FormData object. As you might know, when you have a form that uploads files you need to set the enctype attribute on the form to multipart/form-data which encodes the form values as multipart MIME parts. fetch applies this encoding and sets the content-type to multipart/form-data, so there is no need to specify it

Leave a comment

Leave a Reply

%d bloggers like this: