Récupérer l'API vs XMLHttpRequest

163

Je sais que Fetch API utilise des Promises et les deux vous permettent de faire des requêtes AJAX à un serveur.

J'ai lu que Fetch API avait des fonctionnalités supplémentaires, qui ne sont pas disponibles dans XMLHttpRequest(et dans le polyfill de l'API Fetch, car il est basé sur XHR).

Quelles sont les fonctionnalités supplémentaires de l'API Fetch?

ilyabasiuk
la source
2
Bien que je ne me souvienne pas sur place, il y a une ou deux choses que vous pouvez faire avec XHR que vous ne pouvez pas récupérer. Vous dites que vous avez lu que la récupération a des possibilités supplémentaires, ces articles ne sont pas très bons s'ils ne disent pas ce qu'ils sont
Jaromanda X
2
trouvé les deux choses que vous ne pouvez pas faire avec fetch que vous pouvez avec XHR ... vous ne pouvez pas définir votre propre valeur pour le délai d'expiration de la requête dans fetch, ni obtenir des événements de progression
Jaromanda X
3
Fetch n'est qu'une manière simplifiée de faire les choses pour la plupart des types de XMLHttpRequests. Si votre cas d'utilisation correspond à ce que fait Fetch, utilisez-le. Quand vous y arrivez, l'API XMLHttpRequest est moche pour ce que la plupart des gens l'utilisent. Fetch était un effort pour offrir une manière plus propre de faire les choses qui n'a pas besoin d'une bibliothèque enveloppée autour de XMLHttpRequest pour la rendre acceptable.
jfriend00
1
Il a un support pur dans les navigateurs ( caniuse.com/#search=fetch ), donc il existe un polifill pour cela github.com/github/fetch , qui fonctionne au-dessus de xhr
ilyabasiuk
4
@Marco - Comment ne pas dire que ce fetch(url).then(function(data) (...));n'est pas plus simple que d'utiliser XMLHttpRequestpour faire la même chose? Il peut avoir beaucoup d'autres fonctionnalités, mais bon sang, il est certainement plus simple à utiliser pour les choses courantes. C'est une API nettoyée.
jfriend00

Réponses:

120

Il y a quelques choses que vous pouvez faire avec Fetch et non avec XHR:

  • Vous pouvez utiliser l'API Cache avec les objets de requête et de réponse;
  • Vous pouvez effectuer des no-corsrequêtes, obtenir une réponse d'un serveur qui n'implémente pas CORS. Vous ne pouvez pas accéder au corps de la réponse directement depuis JavaScript, mais vous pouvez l'utiliser avec d'autres API (par exemple l'API Cache);
  • Streaming des réponses (avec XHR, toute la réponse est mise en mémoire tampon, avec Fetch, vous pourrez accéder au flux de bas niveau). Ce n'est pas encore disponible dans tous les navigateurs, mais le sera bientôt.

Il y a quelques choses que vous pouvez faire avec XHR que vous ne pouvez pas encore faire avec fetch, mais elles seront disponibles tôt ou tard (lisez le paragraphe "Améliorations futures" ici: https: //hacks.mozilla .org / 2015/03 / this-api-is-so-fetching / ):

  • Abandonner une requête (cela fonctionne maintenant dans Firefox et Edge, comme l'explique @sideshowbarker dans son commentaire);
  • Signaler les progrès.

Cet article https://jakearchibald.com/2015/thats-so-fetch/ contient une description plus détaillée.

Marco
la source
1
La spécification de l'API Fetch prévoit désormais l'annulation. Le support a jusqu'à présent été fourni dans Firefox 57 et Edge 16. Démos: fetch-abort-demo-edge.glitch.me , mdn.github.io/dom-examples/abort-api . Et il y a des bogues de fonctionnalité Chrome et Webkit ouverts : bugs.chromium.org/p/chromium/issues/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980 . Mode d' emploi : développeurs.google.com /web/updates/2017/09/abortable- fetch , developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples . Et exemple dans la réponse Stack Overflow à stackoverflow.com/a/47250621/441757
Sideshowbarker
1
Une autre différence est que les fetchdemandes ne peuvent pas être rejouées sur les outils de développement.
Parziphal
Et, d'après mon expérience, fetchpeut demander des fichiers, mais XHR ne le peut pas.
D. Pardal
64

chercher

  • manque une méthode intégrée pour consommer des documents
  • aucun moyen de définir un délai d' attente encore
  • impossible de remplacer l'en-tête de réponse de type de contenu
  • si l'en-tête de réponse content-length est présent mais non exposé , la longueur totale du corps est inconnue pendant le streaming
  • appellera le gestionnaire d'abandon du signal même si la demande est terminée
  • pas de progression de téléchargement (le support des ReadableStreaminstances en tant que corps de requête est encore à venir )

XHR

  • il n'y a aucun moyen de ne pas envoyer de cookies (à part l'utilisation du drapeau non standardmozAnon ou du AnonXMLHttpRequestconstructeur)
  • impossible de renvoyer des FormDatainstances
  • ne dispose pas d'équivalent fetchde » no-corsmode
  • suivez toujours les redirections
Knu
la source
13
fetchmanque également de progrès. avec XHR, vous pouvez suivre les progrès de l' progressévénement
rzr
1
"ne peut pas remplacer l'en-tête de type de contenu de la réponse" ... c'est juste une mauvaise idée pour commencer. le 'content-type dicte ce qui doit être retourné et le BACKEND DEVRAIT le dicter au frontend. EN FAIT, le type de contenu doit être le 'SEUL EN-TÊTE' pour le type car ce qui est demandé est ce qui doit être retourné. Si vous voulez quelque chose de différent, diffusez à partir d'un sous-domaine spécial ou de quelque chose pour que vous puissiez gérer des fonctionnalités spécifiques séparément. Vous essayez d'imposer une règle de 1% à 99% de la gorge de tout le monde.
Orubel
@Knu yep et maintenant nous sommes plus avancés et nous pouvons facilement automatiser une solution à 90% et laisser les cas anormaux se diriger vers différentes fonctionnalités.
Orubel
1
@rzr pas exactement, vous avez Response#body.
Knu
9

Les réponses ci-dessus sont bonnes et fournissent de bonnes informations, mais je partage le même avis que celui partagé dans cette entrée de blog des développeurs Google en ce que la principale différence (d'un point de vue pratique) est la commodité de la promesse intégrée renvoyée parfetch

Au lieu d'avoir à écrire du code comme celui-ci

function reqListener() {
    var data = JSON.parse(this.responseText);
}

function reqError(err) { ... }

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

nous pouvons nettoyer les choses et écrire quelque chose d'un peu plus concis et lisible avec des promesses et une syntaxe moderne

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Felipe
la source
8
@TheOpti Vous pouvez polyfill la prise en charge de l'extraction de base dans IE 11. Vous pouvez également simplement supprimer IE11 en tant que navigateur pris en charge dans de nombreux projets, car dans de nombreuses bases d'utilisateurs, l'utilisation d'IE 11 est maintenant inférieure à 1%.
Devon Holcombe