fetch() is a Promise-based API for making HTTP requests in browsers. Being Promise-based, we can use async / await to write "synchronous" styled functions for better code management.
Sample Code
<input type="file" id="file-to-upload" />
<button id="upload-button">Upload</button>
document.querySelector("#upload-button").addEventListener('click', async function() {
let upload = await uploadFile();
if(upload.error == 0)
alert('File uploaded successful');
else if(upload.error == 1)
alert('File uploading failed - ' + upload.message);
});
// async function managing upload operation
async function uploadFile() {
// function return value
let return_data = { error: 0, message: '' };
try {
// no file selected
if(document.querySelector("#file-to-upload").files.length == 0) {
throw new Error('No file selected');
}
else {
// formdata
let data = new FormData();
data.append('title', 'Sample Title');
data.append('file', document.querySelector("#file-to-upload").files[0]);
// send fetch along with cookies
let response = await fetch('/upload.php', {
method: 'POST',
credentials: 'same-origin',
body: data
});
// server responded with http response != 200
if(response.status != 200)
throw new Error('HTTP response code != 200');
// read json response from server
// success response example : {"error":0,"message":""}
// error response example : {"error":1,"message":"File type not allowed"}
let json_response = await response.json();
if(json_response.error == 1)
throw new Error(json_response.message);
}
}
catch(e) {
// catch rejected Promises and Error objects
return_data = { error: 1, message: e.message };
}
return return_data;
}
- All async functions return a Promise which resolves to the value returned by the function, or rejected with an uncaught exception in the function.
In this case the async function "uploadFile" returns a Promise that is always resolved with an object denoting uploading success or error (we are handling exceptions in the function, so the returned Promise is never rejected). - The Promise returned by fetch() is rejected only on network errors — DNS lookup error, user is offline etc. The Promise will be resolved even on error HTTP codes such as 404 and 500.
- response.status returns the HTTP status code of the response.
- For this current example, the server sends a JSON response of the type {"error":0,"message":""} / {"error":1,"message":"Error Message"} with HTTP status 200.
- response.json() returns a Promise that resolves to the parsed JSON object.
- await operator waits for the given Promise to be fulfilled. It needs to be placed inside an async function.
- FormData object automatically sets the Content-Type of the upload request as "multipart/form-data".
Getting Upload Progress for Fetch Request
Currently fetch() does not support tracking upload progress. However XMLHttpRequest has an upload progress event.