[Translation] XMLHttpRequest and Fetch, who is best suited to AJAX?

Original Address: https://www.sitepoint.com/xmlhttprequest-vs-the-fetch-api-whats-best-for-ajax-in-2019/

table of Contents

2019 is the 20th anniversary of the birth of ajax. It can be said, XMLHttpRequestfor the first time achieved is released as IE5.0 ActiveX components in 1999.

Prior to this, there have been a number of ways to get data from the server without refreshing the page, but they usually rely on clumsy techniques, such as <script>injection or third-party plug-ins. Microsoft developed XMLHttpRequestthe initial version, to replace the browser-based Outlook e-mail client.

XMLHttpRequestUntil 2006 as a Web standard, but before this has been implemented in most browsers. Because it uses in Gmail and in Google Maps, Jesse James Garrett published an article in 2005: AJAX:. A New Approach to Web Applications This new term has attracted the attention of developers.

From AJAX to Ajax

AJAX is short for Asynchronous JavaScript and XML. "Asynchronous" word is clear, however:

  1. Although VBScript and Flash can be achieved, but JavaScript is more appropriate
  2. Payload need not be XML, although very popular at that time. Today, you can use any data format JSON is generally preferred.

Now, we will "Ajax" as a client to retrieve data from the server and dynamically update the DOM, without refreshing the entire page of a generic term. Ajax is the most single-page Web applications and applications (SPA) core technology.

XMLHttpRequest

The following code shows how to use the JavaScript XMLHttpRequest(often referred to as XHR) to http://domain/serviceHTTP GET requests made.

let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://domain/service');

// request state change event
xhr.onreadystatechange = function() {
  // request completed?
  if (xhr.readyState !== 4) return;

  if (xhr.status === 200) {
    // request successful - show response
    console.log(xhr.responseText);
  } else {
    // request error
    console.log('HTTP error', xhr.status, xhr.statusText);
  }
};

// start request
xhr.send();

XMLHttpRequestObject has many properties, methods and events. For example, it can be set and monitored in milliseconds timeout:

// set timeout
xhr.timeout = 3000; // 3 seconds
xhr.ontimeout = () => console.log('timeout', xhr.responseURL);

And progress can be reported event file upload long-running:

// upload progress
xhr.upload.onprogress = p => {
  console.log( Math.round((p.loaded / p.total) * 100) + '%') ;
}

Number of attributes may be confusing, and XMLHttpRequestthe early realization of cross-browser also inconsistent in between. Thus, many libraries and frameworks provide Ajax wrapper function, for example, jQuery.ajax()methods:

// jQuery Ajax
$.ajax('http://domain/service')
  .done(data => console.log(data))
  .fail((xhr, status) => console.log('error:', status));

Fetch

Fetch API is XMLHttpRequesta modern alternative. General Header , Request and Response interface provides consistency, while Promises allow simpler chain and do not need to call a callback async / await.

fetch(
    'http://domain/service',
    { method: 'GET' }
  )
  .then( response => response.json() )
  .then( json => console.log(json) )
  .catch( error => console.error('error:', error) );

Fetch simple, elegant, easy to understand and widely used in PWA Service Worker in. Why not use it to replace the old XMLHttpRequest it?

Unfortunately, Web developers never been so clear. Fetch is not a perfect substitute for Ajax's ...

Browser support

Fetch API has been very good in most browsers support , but does not support all versions of IE. Using the 2017 version of Chrome, Firefox and Safari might also encounter problems. These users may account for only a small part ...... your user base is also possible that major customers. So before coding, be sure to check compatibility!

In addition, compared with the mature XHR object, Fetch API newer, more and receive ongoing updates. These updates are less likely to damage the original code, but the next few years will be some maintenance work.

Default No Cookie

And XMLHttpRequestdifferent, Fetch and will not default to send cookie, so the application authentication may fail. By changing the parameters passed in the second initial value to resolve this problem, for example:

fetch(
  'http://domain/service',
  {
    method: 'GET',
    credentials: 'same-origin'
  }
)

The error will not be denied

Surprisingly, HTTP error (e.g., 404 Page Not Foundor 500 Internal Server Error) does not lead to marked Fetch returns Promise Reject; .catch()will not be executed. Do you want an accurate judgment fetch success, need to include the promise resolved the situation, and then determine at this time response.okis not as true. as follows:

fetch(
    'http://domain/service', 
    { method: 'GET' }
  )
  .then( response => {
    if(response.ok) {
      return response.json();
    }
    throw new Error('Network response was not ok.');
  })
  .then( json => console.log(json) )
  .catch( error => console.error('error:', error) );

Only if the request can not be completed trigger reject, such as a network failure or the request is blocked. This will make error trapping more complex.

Does not support timeout

Fetch does not support time-out, as long as the browser allows, the request will continue. The solution is packaged in a can Fetch Promise, for example:

// fetch with a timeout
function fetchTimeout(url, init, timeout = 3000) {
  return new Promise((resolve, reject) => {
    fetch(url, init)
      .then(resolve)
      .catch(reject);
    setTimeout(reject, timeout);
  }
}

Or Promise.race()decide when to first complete the fetch or timeout, for example:

Promise.race([
  fetch('http://url', { method: 'GET' }),
  new Promise(resolve => setTimeout(resolve, 3000))
])
  .then(response => console.log(response))

Fetch aborted

Through xhr.abort()a very easy to end XHR requests, in addition you can also xhr.onabortsolve function monitoring events.

Before a Fetch request has been unable to abort, but now realized AbortController API browser supports it. This triggers a signal that can be passed to Fetch startup object:

const controller = new AbortController();

fetch(
  'http://domain/service',
  {
    method: 'GET'
    signal: controller.signal
  })
  .then( response => response.json() )
  .then( json => console.log(json) )
  .catch( error => console.error('Error:', error) );

Fetch can call controller.abort()to abort. After the Promise are marked reject, calls the .catch()function.

No Progress

As of this writing, Fetch still support the progress of events. Therefore, it is impossible to display the progress status or large file upload form submission.

XMLHttpRequest vs Fetch?

Finally, select or to see yourself ...... unless your application is required to upload progress bar of IE client. You can also choose to Fetch polyfill with Promise polyfill used in combination in order to execute the code in IE Fetch.

Ajax calls for simpler, XMLHttpRequestlow-level, more complex, and you need wrapper functions. Unfortunately, once you start thinking about timeout, suspend the complexity of calls and error trapping, Fetch will be, too.

Fetch the future can be expected. However, this API is relatively new, it does not provide all the features XHR and cumbersome set certain parameters. Therefore, in the future use, please note the above problems.

Guess you like

Origin www.cnblogs.com/hanksyao/p/12089105.html