Introduction to the javascript fetch() Api
Tags: javascript, codenewbie, webdev
Published: 2020-06-10 13:21:43

The Fetch api is used to fetch data or resources from a server. It allows us to retrieve data from a URL without having to do a full page refresh. The Fetch api is an improvement over the XMLHttpRequest API (XHR).

Here is a basic example of XMLHttpRequest. [Example from MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest).

```javascript
    function reqListener() { 
    	var data = JSON.parse(this.responseText); 
    	console.log(data); 
    } 
    function reqError(err) { 
	    console.log('Fetch Error :-S', err); 
    }
     var oReq = new XMLHttpRequest(); 
     oReq.onload = reqListener; 
     oReq.onerror = reqError; 
     oReq.open('get', './api/some.json', true); 
     oReq.send();
```

And a simple fetch request looks like:

```javascript
  fetch('./api/some.json')
    .then( function(response) {
       if (response.status !== 200) {
          console.log('Looks like there was a problem. Status Code: ' + response.status); 
          return;
        } 
        // Examine the text in the response 
      response.json().then(function(data){
        console.log(data); 
        });
	  }).catch(function(err) { 
        console.log('Fetch Error :-S', err); 
    });
```

**fetch** method accepts the path to a resource that we want to retrieve as a parameter, in this case, `./api/some.json`. It returns a promise that resolves to a [response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object.
The response object represents the response to a request. It contains the response body and also useful properties and methods.
Note: It doesn't matter if the response is bad response (like 404) it will still resolve.

A fetch promise only rejects if the request is incomplete, so we must always check the validity of the response. We can check for inadequate responses using `response.ok`
Fetch responses are represented as [ReadableStreams](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) and must be read to access the body of the response. Response objects have [body interface methods like `.json(),.blob(),` etc](https://developer.mozilla.org/en-US/docs/Web/API/Response). to do this.

**Type Of Requests**


By default, fetch uses the [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) method, which retrieves a specific resource. But fetch can also be performed using other HTTP methods.
The fetch method receives a second optional parameter, init. This parameter allows us to pass the configuration of the fetch request, including the request method, cache mode, credentials, and more.

[Example from Google codelab](https://codelabs.developers.google.com/codelabs/pwa-fetch/index.html#0).

```javascript
  fetch('examples/words.txt', {
    method: 'HEAD'
  }).then( function(response) {
       if (response.status !== 200) {
          console.log('Looks like there was a problem. Status Code: ' + response.status); 
          return;
        } 

    const url = response.url;
    const size = response.headers.get('content-length');
    console.log(`${url} is ${size} bytes`);
	  }).catch(function(err) { 
        console.log('Fetch Error :-S', err); 
    });
 ```   

 In this example, we set the fetch request method to HEAD using the init parameter. HEAD requests are just like GET requests, except the body of the response is empty. This kind of request can be used when all we want is metadata about a file, but we don’t need to transport all of the file’s data.


**CORS**


Fetch (and XMLHttpRequest) follows the same-origin policy. This means that browsers restrict cross-origin HTTP requests from within scripts.

_A cross-origin request occurs when one domain (for example_ [_http://foo.com/_](http://foo.com/)_) requests a resource from a separate domain (for instance_ [_http://bar.com/_](http://bar.com/)_)._

Note: Cross-origin request restrictions are often confusing. Various resources like images, stylesheets, and scripts, are fetched across domains (i.e., cross-origin). However, these are exceptions to the same-origin policy. Cross-origin requests are still restricted from within scripts.

  

Using no-cors mode allows **fetching an opaque response**. This allows us to get a response but prevents accessing the response with JavaScript. The response, however, can still be consumed by other APIs or cached by a service worker.

**Request Headers**

Fetch also supports modifying request headers. We can use [headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers) interface to created Headers object and pass that object in the init parameter. 

[Example from Google codelab](https://codelabs.developers.google.com/codelabs/pwa-fetch/index.html#0).

```javascript

 const customHeaders = new Headers({
    'Content-Type': 'application/json',
    'Content-Length': 'kittens', // Content-Length can't be modified!
    'X-Custom': 'hello world',
  })
  fetch('http://localhost:5000/', {
    method: 'POST',
    // body: formData,
    body: JSON.stringify({ lab: 'fetch', status: 'fun' }),
    headers: messageHeaders
  }).then(validateResponse)
    .then(readResponseAsText)
    .then(showText)
    .catch(logError);
    
```

The [Header interface](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers) enables the creation and modification of [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) objects. Some headers, like `Content-Type` can be modified by fetch. Others, like `Content-Length`, are [guarded](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Guard) and can't be modified (for security reasons).


For more information you can also check out https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API