One of the best kept secrets about Ajax is that its underlying API, XMLHttpRequest, is a terrible way to make Ajax requests. We’ve done a good job of creating some elegant APIS for XHR, but we can do better, and what makes us better is to use the FETCH API! Let’s take a quick look at the new window.fetch method, which is now available on Firefox and Chrome Canary. (Note: It is now available on the latest stable version of Chrome.)

XMLHttpRequest

XHR seems a little complicated to me, and I kind of want to make a joke about why XML is uppercase, but Http is lowercase?? Anyway, this is how you write XHR now:

//XHR...
if(window.XMLHttpRequest){
    //Mozilla,Safari...
    request = new XMLHttpRequest();
}else if(window.ActiveXObject){
    / / IE
    try{
        request = new ActiveXObject('Msxml2.XMLHTTP');
    }
    catch(e){
        try{
            request = new ActiveXObject('Microsoft.XMLHTTP');
        }
        catch(e){}
    }
}
// Open, send
request.open('GET'.'https://davidwalsh.name/ajax-endpoint'.true);
request.send(null);
Copy the code

Of course our JS framework makes the way we use XHR much more elegant, but as you can see from the examples above, XHR is a mess.

Basic Fetch usage

The fetch method is now provided in the global window scope, and the first argument is a URL:

// Url arguments are required, while options are optional
fetch('https://davidwalsh.name/some/url', {
	method: 'get'
}).then(function(response) {
	
}).catch(function(err) {
	// Error :(
});
Copy the code

Much like the latest Battery API, the FETCH API uses Promises to handle results or callbacks:

// Simple response processing
fetch('https://davidwalsh.name/some/url').then(function(response) {
	
}).catch(function(err) {
	// Error :(
});

// Hang more advanced processing logic
fetch('https://davidwalsh.name/some/url').then(function(response) {
	return / /...
}).then(function(returnedValue) {
	// ...
}).catch(function(err) {
	// Error :(
});
Copy the code

If you’re not used to using then, you might as well get used to it… It will soon be everywhere

Request header

Being able to set the request header is important for request flexibility. You can use new Headers() to create a request header

// Create an empty request header instance
var headers = new Headers();

// Add some header fields
headers.append('Content-Type'.'text/plain');
headers.append('X-My-Custom-Header'.'CustomValue');

// Check, get, and set the header fields
headers.has('Content-Type'); // true
headers.get('Content-Type'); // "text/plain"
headers.set('Content-Type'.'application/json');

// Delete a header field
headers.delete('X-My-Custom-Header');

// Add initialization information
var headers = new Headers({
	'Content-Type': 'text/plain'.'X-My-Custom-Header': 'CustomValue'
});
Copy the code

You can change the request header using the append, HAS, GET,set, and DELETE methods. This header can be used by creating a request instance.

var request = new Request('https://davidwalsh.name/some-url', {
	headers: new Headers({
		'Content-Type': 'text/plain'})}); fetch(request).then(function() { /* Process the response */ });
Copy the code

Let’s see what Request and Response do!

Request

A Request instance represents a fragment of a FETCH method call. You can create an advanced, customized Request by handing fetch a Request object:

  • method – GET, POST, PUT, DELETE, HEAD
  • Url – The requested URL
  • Headers – andHeadersThe object on
  • Referrer – The requested referrer
  • Mode-cors, no-cors, and same-origin modes
  • Credentials – Sets whether cookies are sent with the request, and of course, with the same origin policy
  • redirect – follow, error, manual
  • Integrity-sri value
  • Cache-cache mode (default, reload, no-cache)

A simple Request would look something like this:

var request = new Request('https://davidwalsh.name/users.json', {
	method: 'POST'.mode: 'cors'.redirect: 'follow'.headers: new Headers({
		'Content-Type': 'text/plain'})});// Now use it!
fetch(request).then(function() { /* Process the response */ });
Copy the code

Only the first parameter, URL, is required. All properties become read-only after the Request instance is created. Note that Request has a clone method, which is important when using fetch in the Service Worker API. Because a Request is a stream, it must be cloned when another fetch is called.

The fetch method is used to behave just like Request, so you can do this:

fetch('https://davidwalsh.name/users.json', {
	method: 'POST'.mode: 'cors'.redirect: 'follow'.headers: new Headers({
		'Content-Type': 'text/plain'
	})
}).then(function() { /* Process the response */ });
Copy the code

In a Service Worker, you will probably only use Request instances, since Request and fetch are used the same way.

Response

Fetch’s then method provides an instance of Response, but you can manually create a Response object — a situation you might encounter when using Service Workers. You can set Response like this:

  • type – basic, cors
  • url
  • Usefinalurl-boolean Specifies the valueurlIs it the last URL
  • Status – Status code (e.g. 200, 404…)
  • Ok-boolean value, whether the response was successful (status between 200 and 299)
  • StatusText – A literal description of the status code (e.g., OK)
  • Headers – The headers object associated with response
Create your own response to test the Service worker
// new Response(BODY, OPTIONS)
var response = new Response('... ', {
	ok: false.status: 404.url: '/'
});

// Fetch's then method takes an instance of Response
fetch('https://davidwalsh.name/')
	.then(function(responseObj) {
		console.log('status: ', responseObj.status);
	});
Copy the code

The Response object also provides these methods:

  • Clone () – Creates a copy of the Response object
  • Error () – Returns a new Response object about a network error
  • Redirect () – Create a new response with a different URL
  • ArrayBuffer () – Returns a Promise with an arrayBufferresolve
  • Blob () – Returns a promise that carries the BLOBresolve
  • FormData () – Returns a promise that carries the formData objectresolve
  • Json () – Returns a Promise object, one that carries JSONresolve
  • Text () – Returns a return promise object, a carryUSVString(text)resolve

Processing JSON

When you create a request that asks for JSON, the callback it gets will have JSON methods that convert the raw data into JavaScript objects

fetch('https://davidwalsh.name/demo/arsenal.json').then(function(response) { 
	// Convert to JSON
	return response.json();
}).then(function(j) {
	// Yes,j is a JavaScript object
	console.log(j); 
});
Copy the code

Of course, this is a simple JSON.parse(jsonString), but using the JSON method is a convenient shortcut.

Handles basic text /HTML responses

JSON will not always be the desired response format, so here you can see how to handle text or HTML responses.


fetch('/next/page')
  .then(function(response) {
    return response.text();
  }).then(function(text) { 
  	/ / 
      
  	console.log(text); 
  });
Copy the code

You can get the response text by linking the Promise’s then method after the text() method.

Process Blob responses

If you want to load an image via fetch, it will be a little different, for example:

fetch('https://davidwalsh.name/flowers.jpg')
  .then(function(response) {
    return response.blob();
  })
  .then(function(imageBlob) {
    document.querySelector('img').src = URL.createObjectURL(imageBlob);
  });
Copy the code

The Blob() method of the Response takes a Response stream and finishes reading it.

Send the From the Data

Another common case where AJAX is used is sending From Data. Here’s how to use the fetch method to send From Data:

fetch('https://davidwalsh.name/submit-json', {
	method: 'post'.body: JSON.stringify({
		email: document.getElementById('email').value,
		answer: document.getElementById('answer').value
	})
});
Copy the code

Very simple, very pleasing to the eye!

Unwritten little story

Fetch is probably a better API, but the API does not currently support cancellation requests, which would disappoint many developers.

It seems that using the new FETCH API is smarter and simpler than using XHR, and thanks to it we can implement AJAX more correctly. Fetch has the benefit of hindsight and although FETCH is not yet widely supported, I can’t wait!

This is an introduction to FETCH. For more information please go to Introduction to Fetch. If you’re looking for a Polyfill solution, check out GitHub’s Implementation.

Original link: DavidWalsh.name /fetch