Fetch API vs XMLHttpRequest


163

Я знаю, що Fetch API використовує Promises і обидва вони дозволяють робити запити AJAX до сервера.

Я читав, що API Fetch має деякі додаткові функції, які недоступні в XMLHttpRequest(і в поліфайлі Fetch API, оскільки він заснований XHR).

Які додаткові можливості має API Fetch?


2
Хоча я не можу згадати на місці, є одна чи дві речі, які ви можете зробити з XHR, який ви не можете отримати. Ви кажете, що ви читали, що у програми є додаткові можливості, ці статті не дуже гарні, якщо вони не кажуть, що вони є
Jaromanda X

2
знайшли дві речі, з якими ви не можете скористатись XHR ... ви не можете встановити власну цінність часу очікування запиту у завантаженні, а також не можете отримати події прогресу
Jaromanda X

3
Витяг - це просто спрощений спосіб виконання дій для більшості типів XMLHttpRequests. Якщо ваш випадок використання відповідає тому, що робить Fetch, тоді використовуйте його. Коли ви перейдете до нього, API XMLHttpRequest некрасивий для того, для чого його використовують більшість людей. Fetch намагався запропонувати більш чіткий спосіб робити речі, для яких не потрібна бібліотека, обгорнена навколо XMLHttpRequest, щоб зробити її приємною.
jfriend00

1
Він має чисту підтримку у веб-переглядачах ( caniuse.com/#search=fetch ), тому для нього є polifill github.com/github/fetch , який працює над xhr
ilyabasiuk

4
@Marco - Як ти не можеш сказати, що fetch(url).then(function(data) (...));це не простіше, ніж використовувати XMLHttpRequestте саме? У нього може бути безліч інших функцій, але, звичайно, простіше використовувати для звичайних речей. Це очищений API.
jfriend00

Відповіді:


120

Є кілька речей, які ви можете зробити із завантаженням, а не з XHR:

  • Ви можете використовувати API кешу з об’єктами запиту та відповіді;
  • Ви можете виконувати no-corsзапити, отримуючи відповідь від сервера, який не реалізує CORS. Ви не можете отримати доступ до тіла відповіді безпосередньо з JavaScript, але ви можете використовувати його з іншими API (наприклад, API кешу);
  • Потокова відповідь (з XHR вся відповідь буферизована в пам'яті; за допомогою цього ви зможете отримати доступ до потоку низького рівня). Це ще не в усіх браузерах, але буде скоро.

Є кілька речей, які ви можете зробити з XHR, які ще не можете зробити із завантаженням, але вони будуть доступні рано чи пізно (читайте пункт "Майбутнє вдосконалення" тут: https: //hacks.mozilla .org / 2015/03 / this-api-is-so-fetching / ):

  • Відмовитись від запиту (це зараз працює у Firefox та Edge, як пояснює @sideshowbarker у своєму коментарі);
  • Повідомте про хід.

Ця стаття https://jakearchibald.com/2015/thats-so-fetch/ містить більш детальний опис.


1
Специфікація API Fetch тепер передбачає скасування. Підтримка наразі надходить у Firefox 57 та Edge 16. Демо: fetch-abort-demo-edge.glitch.me , mdn.github.io/dom-examples/abort-api . І є відкриті функції Chrome & Webkit bugs bugs.chromium.org/p/chromium/isissue/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980 . Як: розробники.google.com/ web/ updates/ 2017/09/ abortable- fetch , developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples . І приклад у відповіді на переповнення стека на stackoverflow.com/a/47250621/441757
sideshowbarker

1
Ще одна відмінність полягає в тому, що fetchзапити неможливо відтворити в Інструментах для розробників.
Парцифал

З мого досвіду, я fetchможу запитувати файли, але XHR не може.
Д. Пардал

64

приносити

  • відсутній вбудований метод для споживання документів
  • немає можливості встановити тайм - аут ще
  • не може змінити заголовок відповіді типу вмісту
  • якщо заголовок відповіді довжини вмісту присутній, але не піддається впливу , загальна довжина тіла не відома під час трансляції
  • зателефонує обробнику сигналу аборту, навіть якщо запит виконано
  • відсутній прогрес у завантаженні (підтримка ReadableStreamвипадків, оскільки органи запитів ще не надійде )

XHR

  • немає способу не надсилати файли cookie (крім використання нестандартного mozAnonпрапора або AnonXMLHttpRequestконструктора)
  • не може повернути FormDataекземпляри
  • не має еквівалента режиму fetchsno-cors
  • завжди слідкуйте за переадресаціями

13
fetchтакож не вистачає прогресу. за допомогою XHR ви можете відстежувати хід progressподії
rzr

1
"не вдається змінити заголовок типу відповіді відповіді" ... це лише погана ідея. "Тип типу вмісту диктує, що потрібно повернути, і НАЗАД повинен продиктувати це передньому напрямку. В дійсності тип вмісту повинен бути "ТІЛЬКИЙ ГОЛОВНИК" для типу, тому що запитується те, що потрібно повернути. Якщо ви хочете, щоб щось особливе було подано зі спеціального субдомену або чогось іншого, ви можете обробляти певну функціональність окремо. Ви намагаєтесь змусити правило на 1% зменшити 99% горла всіх.
Орубель

@Knu yep, і тепер ми вдосконаленіші, і ми можемо легко автоматизувати 90% рішення і дозволити випадкові справи направляти на різні функції.
Орубель

1
@rzr не зовсім, у вас є Response#body.
Кну

9

Наведені вище відповіді хороші і дають хорошу інформацію, але я поділяю ту саму думку, яку поділяв цей запис у блозі розробників google у тому, що головна відмінність (з практичної точки зору) - зручність вбудованої обіцянки, повернутої зfetch

Замість того, щоб писати такий код

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();

ми можемо очистити речі і написати щось трохи більш стисле і читабельне з обіцянками та сучасним синтаксисом

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });

8
@TheOpti Ви можете перезапустити базову підтримку для отримання інформації в IE 11. Ви також можете просто запустити IE11 як підтримуваний браузер у багатьох проектах, оскільки в багатьох базах користувачів використання IE 11 зараз нижче 1%.
Девон Холкомб
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.