fetch()
позволяет отправлять сетевые запросы, аналогичные XMLHttpRequest (XHR). Основное отличие состоит в том, что API-интерфейс Fetch использует Promises, который имеет более простой API, позволяющий избежать сложных обратных вызовов в API XMLHttpRequest.
Если вы никогда раньше не использовали Promises , ознакомьтесь со статьей «Введение в промисы JavaScript» .
Базовый запрос на получение
Вот пример, реализованный с помощью XMLHttpRequest
а затем с помощью fetch
. Мы хотим запросить URL-адрес, получить ответ и проанализировать его как JSON.
XMLHttpRequest
XMLHttpRequest
требует двух прослушивателей для обработки случаев успеха и ошибок, а также вызова open()
и send()
. Пример из документации MDN .
function reqListener() {
var data = JSON.parse(this.responseText);
console.log(data);
}
function reqError(err) {
console.log('Fetch Error :-S', 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(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
Запросу fetch()
требуется только один вызов, чтобы выполнить ту же работу, что и в примере XHR. Чтобы обработать ответ, мы сначала проверяем, что статус ответа равен 200, а затем анализируем ответ как JSON. Ответом на запрос fetch()
является объект Stream , а это означает, что после вызова метода json()
возвращается обещание. Поток происходит асинхронно.
Метаданные ответа
В предыдущем примере показано состояние объекта Response и способ анализа ответа в формате JSON. Вот как обрабатывать другие метаданные, к которым вам может понадобиться доступ, например заголовки:
fetch('users.json').then(function(response) {
console.log(response.headers.get('Content-Type'));
console.log(response.headers.get('Date'));
console.log(response.status);
console.log(response.statusText);
console.log(response.type);
console.log(response.url);
});
Типы ответов
Когда мы делаем запрос на выборку, ответу будет присвоен response.type
« basic
», « cors
» или « opaque
». Эти types
показывают, откуда взялся ресурс, и вы можете использовать их, чтобы определить, как обращаться с объектом ответа.
Когда браузер запрашивает ресурс из того же источника, ответ имеет basic
тип с ограничениями на то, что вы можете просмотреть из ответа.
Если запрос делается для ресурса в другом источнике, и этот источник возвращает заголовки COR , тогда тип — cors
. Ответы cors
аналогичны basic
ответам, но они ограничивают заголовки, которые вы можете просматривать, Cache-Control
, Content-Language
, Content-Type
, Expires
, Last-Modified
и Pragma
.
opaque
ответы приходят из другого источника, который не возвращает заголовки CORS. При непрозрачном ответе мы не сможем прочитать возвращенные данные или просмотреть статус запроса, то есть вы не сможете проверить, был ли запрос успешным.
Вы можете определить режим запроса на выборку, чтобы разрешались только определенные типы запросов. Вы можете установить следующие режимы:
-
same-origin
успешен только для запросов на активы из того же источника и отклоняет все остальные запросы. -
cors
позволяет запрашивать активы из того же и других источников, которые возвращают соответствующие заголовки COR. -
cors-with-forced-preflight
выполняет предполетную проверку перед выполнением любого запроса. -
no-cors
предназначен для отправки запросов к другим источникам, которые не имеют заголовков CORS и приводят кopaque
ответу, но, как уже говорилось, в настоящий момент это невозможно в глобальной области видимости окна.
Чтобы определить режим, добавьте объект параметров в качестве второго параметра в запросе fetch
и определите режим в этом объекте:
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(function(response) {
return response.text();
})
.then(function(text) {
console.log('Request successful', text);
})
.catch(function(error) {
log('Request failed', error)
});
Цепочка обещаний
Одной из замечательных особенностей промисов является возможность связывать их вместе. Для fetch()
это позволяет вам совместно использовать логику между запросами выборки.
Если вы работаете с API JSON, вам необходимо проверять статус и анализировать JSON для каждого ответа. Вы можете упростить свой код, определив статус и анализ JSON в отдельных функциях, которые возвращают обещания, и использовать запрос на выборку для обработки только окончательных данных и случая ошибки.
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json(response) {
return response.json()
}
fetch('users.json')
.then(status)
.then(json)
.then(function(data) {
console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
console.log('Request failed', error);
});
В этом примере определяется функция status
, которая проверяет response.status
и возвращает либо решенное обещание как Promise.resolve()
, либо отклоненное обещание как Promise.reject()
. Это первый метод, вызываемый в цепочке fetch()
.
Если промис разрешается, сценарий затем вызывает метод json()
, который возвращает второй промис из вызова response.json()
и создает объект, содержащий проанализированный JSON. Если синтаксический анализ завершается неудачей, обещание отклоняется и выполняется оператор catch.
Эта структура позволяет вам использовать логику для всех ваших запросов на выборку, что упрощает обслуживание, чтение и тестирование кода.
POST-запрос
Иногда веб-приложению необходимо вызвать API с помощью метода POST и включить некоторые параметры в тело запроса. Для этого установите параметры method
и body
в опциях fetch()
:
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(function (data) {
console.log('Request succeeded with JSON response', data);
})
.catch(function (error) {
console.log('Request failed', error);
});
Отправка учетных данных с запросом на получение
Чтобы выполнить запрос на выборку с учетными данными, такими как файлы cookie, установите credentials
запроса значение "include"
:
fetch(url, {
credentials: 'include'
})