Comparing different ways to make HTTP requests in Javascript in 2020

Concise and useful — make it easy.

Kesk -*-
Kesk -*-
Mar 4 · 6 min read
Image for post
Image for post
Image of two monitors with code in their screens

Recently I had to decide what technology to use for a large javascript project to make ajax calls. If you are using JavaScript, you have different chances to make call requests.

In the beginning, there had been some methods to pull data from a server without a page refresh, but they often relied on clunky techniques. Microsoft developed XMLHttpRequest for a browser alternative to their Outlook email client. XMLHttpRequest became a web standard in 2006.

The Fetch API was introduced in 2015 with ES6. The generic Request and Response interfaces provide consistency while Promises permit easier chaining and async/await without callbacks. Fetch is clean, elegant, and simple to understand, but there are other good alternatives, and we will see them briefly in this article.

To keep it simple, I will focus on what they are, their syntaxes, and some pros and cons of each option.

  • XMLHttpRequest
  • JQuery.ajax
  • Qwest
  • SuperAgent
  • Http-client
  • Axios
  • Fetch
  • <Request> I will not talk about it since it is deprecated.

The following code shows a basic HTTP GET and POST examples using different alternatives. Let’s start then.

XMLHttpRequest

The XMLHttpRequest object can be used to request data from a web server. It Is the oldest method of this comparison, and although other options surpass it, it is still valid and useful for its backward compatibility and maturity.

Get

var req = new XMLHttpRequest();//The onreadystatechange property
//specifies a function to be
//executed every time the status
//of the XMLHttpRequest changes
req.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//The responseText property
//returns a text string
console.log(xhttp.responseText)
//Do some stuff
}
};
req.open("GET", "http://dataserver/users", true);
req.send();

Post

var formData = new FormData();
formData.append("name", "Murdock");
var req = new XMLHttpRequest();
req.open("POST", "http://dataserver/update");
req.send(formData);

Pros

  • Work in all browsers
  • Is a native browser API
  • It is not is necessary to load it from an external source
  • Backward compatibility
  • Mature/stable

Cons

  • Clunky and verbose syntax
  • Favors callback hell
  • Fetch replaces it natively

JQuery.ajax

Library widely used until a while ago to make HTTP asynchronous requests.

All of jQuery’s Ajax methods return a superset of the XMLHTTPRequest object

Get

$.ajax({
url: 'http://dataserver/data.json'
}).done(function(data) {
// ...do some stuff whith data
}).fail(function() {
// Handle error
});

Post

$.ajax({
type: "POST",
url: 'http://dataserver/update',
data: data,
success: successCallBack,
error: errorCallBack,
dataType: dataType
});

Pros

  • Good support and documentation
  • Configurable object
  • It is in many projects
  • Low learning curve
  • You can abort the request because it returns an XMLHttpRequest object.

Cons

  • Not is native
  • It is necessary to load it from an external source
  • All JQuery functionalities are added, not only those necessary to make HTTP requests.

Qwest

Qwest is a simple ajax library based on promises, and that supports XmlHttpRequest2 unique data like ArrayBuffer, Blob, and FormData.

Get

qwest.get('http://dataserver/data.json')
.then(function(xhr, response) {
// ...do some stuff whith data
});

Post

qwest.post('http://dataserver/update', {
firstname: 'Murdock',
age: 30
})
.then(function(xhr, response) {
// Make some useful actions
})
.catch(function(e, xhr, response) {
// Process the error
});

Pros

  • You can establish a request limit
  • Promise-based

Cons

  • XmlHttpRequest2 is not available on every browser
  • Not is native
  • It is necessary to load it from an external source

SuperAgent

SuperAgent is ajax API created for flexibility, readability, and with a low learning curve. It also works with Node.js

Get

request('GET', 'http://dataserver/data.json').then(
success, failure);

The .query() method accepts objects, which, when used with the GET method, will form a query-string. The following will produce the path /dataserver/search?name=Manny&lastName=Peck&order=desc.

request
.get('/dataserver/search')
.query({ name: 'Templeton' })
.query({ lastname: 'Peck' })
.query({ order: 'desc' })
.then(res => {console.dir(res)}
});

Post

request
.post('http://dataserver/update')
.send({ name: 'Murdock' })
.set('Accept', 'application/json')
.then(res => {
console.log('result' + JSON.stringify(res.body));
});

Pros

  • Promise-based
  • Works in both Nodejs and Browser
  • To abort a request, invoke the request.abort() method
  • Well-known library in the community
  • Seamless interface to make HTTP requests
  • Support retry requests when there is a fault

Cons

  • It does not support monitoring load progress as XMLHttpRequest
  • Not is native
  • It is necessary to load it from an external source

Http-client

Http-client lets you compose HTTP clients using JavaScript’s fetch API.

Get

//using ES6 modules
import { createFetch, base, accept, parse } from 'http-client'
const fetch = createFetch(
base('http://dataserver/data.json'),
accept('application/json'),
parse('json')
)
fetch('http://dataserver/data.json').then(response => {
console.log(response.jsonData)
})

Post

//using ES6 modules
import { createFetch, method, params } from 'http-client'
const fetch = createFetch(
params({ name: 'Murdock' }),
base('http://dataserver/update')
)

Pros

  • It works on both Browser and Nodejs
  • Used by Service Workers
  • Promise-based
  • Provides header guards for better CORS safety

Cons

  • Not is native
  • It is necessary to load it from an external source

Axios

Promise-based HTTP library for performing HTTP requests on both Browser and Nodejs.

Get

axios({
url: 'http://dataserver/data.json',
method: 'get'
})

Post

axios.post('http://dataserver/update', {
name: 'Murdock'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

Pros

  • Uses promises to avoid callback hell
  • It works on both Browser and Nodejs
  • Support for upload progress
  • Can set a response timeout
  • Configure your requests by simply passing a configuration object to it
  • Axios has implemented the cancellable promise proposal
  • Automatically converts the data to JSON

Cons

  • Not is native
  • It is necessary to load it from an external source

Fetch

Fetch is a native browser API to make a request that replaces XMLHttpRequest. Fetch allows making network requests easier than with XMLHttpRequest. The Fetch API uses Promises avoiding XMLHttpRequest callback hell.

Get

//With ES6 fetch
fetch('http://dataserver/data.json')
.then(data => {
// ...do some stuff whith data
}).catch(error => {
// Handle error
});

Post

fetch('http://dataserver/update', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: 'Murdock'})
}).then(res=>res.json())
.then(res => console.log(res));
//OR with ES2017 for example(async () => {

const response = await fetch(‘http://dataserver/update’, {
method: ‘POST’,
headers: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/json’
},
body: JSON.stringify({name:’Murdock’})
});
const result = await response.json();console.log(result);
})();

Pros

  • Is a native browser API
  • Fetch is basically XMLHttpRequest done right
  • Not is necessary to load it from an external source
  • Uses promises to avoid callback hell
  • No need of more dependencies
  • Is friendly and easy to learn
  • Is compatible in most of the commonly recent used browsers
  • Is the natural replace of native XMLHttpRequest object
  • Low learning curve

Cons

  • It is a two-step process when handling JSON data. The first is to make the request, and then the second is to call the .json() method on response. On Axios, you get JSON response by default.
  • The Promise returned from Fetch () only reject on network failure or if anything prevented the request from completing. Won’t reject on HTTP error status even if the response is an HTTP 404 or 500
  • Lacks some useful features of other libraries like for example: canceling requests
  • Fetch won’t send or receive by default cookies from the server, resulting in unauthenticated requests if the site relies on maintaining a user session. But you can enable with adding: {
    credentials: “same-origin.”
    }

Conclusion

Fetch is the new standard and is supported by new versions of Chrome and Firefox without using any additional library.

It is recommended to dedicate some time to look at the characteristics of Axios, SuperAgent, or the rest of the libraries as they all have proper documentation, are easy to use, and their learning curve is not too large. For some instances, they offer features that do not have Fetch.

In my case, I will use Fetch because I don’t need special features, and Fetch is native in JavaScript and enough for my project.

Thanks for reading. I hope this helps you two know the different ways of dealing with asynchronous code in JavaScript.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store