В чем разница между Fetch API и XMLHttpRequest?


Я знаю, что fetch использует обещания, и оба они позволяют выполнять запросы AJAX на сервер. Я читал, что fetch имеет некоторые дополнительные функции, которые недоступны в XMLHttpRequest (и в fetch polyfill, поскольку он основан на XHR). Какие дополнительные возможности имеет API выборки?

3 103

3 ответа:

есть несколько вещей, которые вы можете сделать с fetch, а не с XHR с:

  • вы можете использовать API кэша с объектами запроса и ответа;
  • вы можете выполнить no-cors запросы, получение ответа от сервера, который не реализует CORS. Вы не можете получить доступ к телу ответа непосредственно из JavaScript, но вы можете использовать его с другими API (например, API кэша);
  • потоковые ответы (с XHR весь ответ буферизуется в памяти, с fetch вы сможете получить доступ к потоку низкого уровня). Это еще не доступно во всех браузерах, но скоро будет.

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

  • прервать запрос (теперь это работает в Firefox и Edge, как @sideshowbarker объясняет в своем комментарии);
  • отчет.

эта статья https://jakearchibald.com/2015/thats-so-fetch/ содержит более подробное описание.

fetch

  • отсутствует встроенный метод для использования документов
  • нет способа установить тайм-аут пока
  • не удается переопределить заголовок ответа типа содержимого
  • если заголовок ответа content-length присутствует но не подвергнутый, общая длина тела неизвестна во время потоковой передачи
  • вызовет обработчик прерывания сигнала даже если запрос был завершено

XHR

  • нет не отправить куки (кроме использования нестандартное mozAnon флаг или AnonXMLHttpRequest конструктор)
  • не могу вернуть FormData экземпляров
  • не имеет эквивалента fetch ' s no-cors режим
  • всегда следуйте перенаправляет

ответы выше хороши и дают хорошие идеи, но я разделяю то же мнение, что и в этом запись в блоге разработчиков 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) => { ... });