73

What is the difference between typical AJAX and Fetch API?

Consider this scenario:

function ajaxCall(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      } else {
        reject(Error(req.statusText));
      }
    };
    req.onerror = function() {
      reject(Error("Network Error"));
    };
    req.send();
  });
}

ajaxCall('www.testSite').then(x => {
  console.log(x)
}) // returns html of site

fetch('www.testSite').then(x => {
  console.log(x)
}) // returns object with information about call

This is what the fetch call returns:

Response {type: "cors", url: "www.testSite", status: 200, ok: true, statusText: "OK"…}

Why does it return different things?

Is there a way for fetch to return the same thing as a typical AJAX call?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Darlyn
  • 4,715
  • 12
  • 40
  • 90
  • 3
    Possible duplicate of [What is the difference between the Fetch API and XMLHttpRequest?](http://stackoverflow.com/questions/35549547/what-is-the-difference-between-the-fetch-api-and-xmlhttprequest) – Marco Castelluccio Jul 12 '16 at 16:35
  • 2
    FYI: Fetch isn't supported by IE11 (although there's a Polyfill for it: https://github.com/github/fetch) – Chuck Le Butt Sep 11 '17 at 11:50

2 Answers2

60

The Fetch API has built in methods for different datatypes.
For just regular text/html you'd use the text() method, which returns a promise as well, and chain it with another then call.

fetch('www.testSite').then( x => { 
    return x.text();
}).then( y => {
    console.log(y);
});

The built-ins for the returned content is as follows

  • clone() - Creates a clone of a Response object.
  • error() - Returns a new Response object associated with a network error.
  • redirect() - Creates a new response with a different URL.
  • arrayBuffer() - Returns a promise that resolves with an ArrayBuffer.
  • blob() - Returns a promise that resolves with a Blob.
  • formData() - Returns a promise that resolves with a FormData object.
  • json() - Returns a promise that resolves with a JSON object.
  • text() - Returns a promise that resolves with a USVString (text).

It also allows you to send things to the server, or add your own headers etc.

fetch('www.testSite', {
    method  : 'post',
    headers : new Headers({
        'Content-Type': 'application/x-www-form-urlencoded'
    }),
    body    : new FormData(document.getElementById('myform'))
}).then( response => {
    return response.json(); // server returned valid JSON
}).then( parsed_result => {
    console.log(parsed_result);
});
Mike
  • 14,010
  • 29
  • 101
  • 161
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • 2
    Only recently `fetch` was added the option to being [aborted](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort) (why was `fetch` originally released without a way of aborting is beyond me). *Ajax* can be *aborted* much easier. – vsync Oct 02 '18 at 20:30
  • A `Promise` cannot be aborted. This is, perhaps, the limitation of the initial implementation. I wonder how they have worked around this. – esengineer Feb 09 '19 at 18:53
  • this can be shortened a bit with .then(response => response.json()) – smoore4 Feb 26 '22 at 23:35
9

Your ajaxCall is returning the responseText from the XMLHttpRequest object. It is filtering it out.

You need to read the response Text in the fetch code.

fetch('/foo/').then(x => x.text()).then(console.log)

You can also use x.json() or x.blob()

pnijo
  • 3
  • 2
epascarello
  • 204,599
  • 20
  • 195
  • 236