fetch replaces xhr and $.ajax on many terms. Here are a few templates and blueprints to use

Article on my blog

How to monitor the progress of a Javascript fetch - request and cancel it on demand.

Basic options

const options = {
  method: "POST",             // *GET, POST, PUT, DELETE, 
  mode: "cors",               // no-cors, cors, *same-origin
  cache: "no-cache",          // *default, no-cache, reload, force-cache, only-if-cached
  credentials: "same-origin", // include, *same-origin, omit
  headers: {
    "Content-Type": "application/json", 
    // "Content-Type": "application/x-www-form-urlencoded",
  },
  redirect: "follow",         // manual, *follow, error
  referrer: "no-referrer",    // no-referrer, *client,
  body: JSON.stringify(data)
}

fetch(url, options).then(res => res.json())

Different responsecontent types that can be handled

fetch(url)
.then(res => {
  res.text()       // response body (=> Promise)
  res.json()       // parse via JSON (=> Promise)
  res.status       //=> 200
  res.statusText   //=> 'OK'
  res.redirected   //=> true/false
  res.ok           //=> true/false
  res.url          //=> '<http://site.com/data.json>'
  res.type         //=> 'basic'
                   //   ('cors' 'default' 'error'
                   //    'opaque' 'opaqueredirect')
  res.headers.get('Content-Type')
})

Monitor progress of fetch

// instead of response.json() and other methods
const reader = response.body.getReader();

// infinite loop while the body is downloading
while(true) {
  // done is true for the last chunk
  // value is Uint8Array of the chunk bytes
  const {done, value} = await reader.read();

  if (done) {
    break;
  }

  console.log(`Received ${value.length} bytes`)
}

Fetch in the backend

const fetch = require('isomorphic-fetch')

Send an abort after fetch has already been executed

// setup AbortController
const controller = new AbortController();

// signal to pass to fetch
const signal = controller.signal;

// fetch as usual with abort controller signal as option
fetch(url, { signal }).then(response => {
  ...
}).catch(e => {
  // catch the abort if you like
  if (e.name === 'AbortError') {
    ...
  }
});

// when you want to abort
controller.abort();