Функция fetch() может дополнительно принимать опции запроса в виде второго необязательного параметра:
fetch(resource [, init])
Параметр init представляет сложный объект, который может имеет большой набор опций:
method: метод запроса, например, GET, POST, PUT и т.д.
headers: устанавливаемые в запросе заголовки
body: тело запроса - данные, которые добавляются в запрос.
mode: режим запроса, например, cors, no-cors и same-origin
credentials: определяет действия с учетными данными (куки, данные HTTP-аутентификации и сертификаты клиента TLS). Принимает одно из следующих значений:
omit: учетные данные исключаются из запроса, а любые учетные данные, присланные в ответе от сервера, игнорируютсяsame-origin: учетные данные включаются только в те запросы и принимаются в ответах только на те запросы, адрес которых принадлежит
к тому же домену, что и адрес клиента.include: учетные данные включаются в любые запросы и принимаются в ответах на любые запросыcache: устанавливает принцип взаимодействия с кэшем браузера. Возможные значения: default, no-store, reload, no-cache, force-cache и
only-if-cached
redirect: устанавливает, как реагировать на редиректы. Может принимать следующие значения:
follow: автоматически применять редиректerror: при редиректе генерировать ошибкуmanual: обрабатывать ответ в другом контекстеreferrer: определяет реферера запроса
referrerPolicy: определяет политику реферера - как информация о реферере будет передаваться в запросе.
Может принимать следующие значения: no-referrer, no-referrer-when-downgrade, same-origin, origin, strict-origin, origin-when-cross-origin,
strict-origin-when-cross-origin и unsafe-url
integrity: содержит контрольное значение ресурса
keepalive: позволяет запросу существовать дольше, чем время жизни веб-страницы.
signal: предоставляет объект AbortSignal и позволяет отменить выполнение запроса.
Пример настройки опций:
fetch("/user", {
method: "GET",
headers: { "Accept": "application/json" }
})
.then(response => response.json())
.then(user => console.log(user));
В данном случае устанавливаем метод запроса - "GET" и заголовок "Accept" - его значение "application/json" говорит, что клиент принимает данные в формате json.
Стоит отметить, что свойство headers представляет объект Headers. Мы можем применять методы данного объекта для установки заголовков:
const myHeaders = new Headers();
myHeaders.append("Accept", "application/json");
fetch("/user", {
method: "GET",
headers: myHeaders
})
.then(response => response.json())
.then(user => console.log(user));
Метод append() добавляет определенный заголовок, название которого передается через первый параметр, а значение заголовка - через второй параметр.
Также можно использовать метод set() для установки заголовка, а если заголовок уже ранее добавлен, то метод set() заменяет его значение.
Если же надо удалить ранее добавленный заголовок, то можно использовать метод delete(), который получает имя удаляемого заголовка:
const myHeaders = new Headers();
myHeaders.append("Accept", "application/json"); // добавляем заголовок Accept
myHeaders.set("Accept", "text/xml"); // Изменяем значение заголовка
myHeaders.delete("Accept"); // Удаляем заголовок
Для отправки данных в запросе в функции fetch() применяется в рамках второго параметра применяется опция body.
Эти данные могут представлять типы Blob, BufferSource, FormData, URLSearchParams, USVString и ReadableStream. Стоит учитывать, что в запросах с методом GET и HEAD
для запроса нельзя установить эту опцию.
Для тестирования отправки определим простейший сервер на node.js, который принимает данные:
const http = require("http");
const fs = require("fs");
http.createServer(async (request, response) => {
if(request.url == "/user"){
const buffers = []; // буфер для получаемых данных
// получаем данные из запроса в буфер
for await (const chunk of request) {
buffers.push(chunk);
}
// получаем строковое представление ответа
let userName = Buffer.concat(buffers).toString();
userName = userName + " Smith";
response.end(userName);
}
else{
fs.readFile("index.html", (error, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
В данном случае при обращении по адресу "/user" сервер получает все отправленные данные. Объект запроса предоставляет итератор для извлечения данные. И в коде сервера эти данные передаются в специальный массив-буфер:
for await (const chunk of request){
buffers.push(chunk);
}
Затем с помощью метода Buffer.concat() объединяем все полученные данные и формируем из них строку:
let userName = Buffer.concat(buffers).toString();
В данном случае мы предполагаем, что на сервер отправляется простая строка с текстом. Пусть она представляет некоторое имя пользователя. И для примера к этому имени добавляется фамилия и измененное имя отправляется обратно клиенту:
userName = userName + " Smith"; response.end(userName);
Теперь определим на странице index.html код для отправки данных на этот сервер:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
</head>
<body>
<script>
fetch("/user", { method: "POST", body: "Tom" })
.then(response => response.text())
.then(userName => console.log(userName));
</script>
</body>
</html>
Для отправки применяется метод POST. А в качестве отправляемых данных выступает простая строка "Tom". Таким образом, мы отправляем простой текст.
И поскольку сервер в ответ также отправляет текст, то для получения ответа здесь применяется метод response.text().
И при запуске данной веб-страницы будет выполняться отправка данных на сервер, и в консоли браузера мы сможем лицезреть полученный от сервера ответ:
Подобным образом можно отправлять более сложные по структуре данные. Например, рассмотрим отправку json. Для этого на строне node.js определим следующий сервер:
const http = require("http");
const fs = require("fs");
http.createServer(async (request, response) => {
if(request.url == "/user"){
const buffers = [];
for await (const chunk of request) {
buffers.push(chunk);
}
const data = Buffer.concat(buffers).toString();
const user = JSON.parse(data); // парсим строку в json
// изменяем данные полученного объекта
user.name = user.name + " Smith";
user.age += 1;
// отправляем измененый объект обратно клиенту
response.end(JSON.stringify(user));
}
else{
fs.readFile("index.html", (error, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
В данном случае на сервера ожидаем, что мы получим объект в формате json, который имеет два свойства - name и age. Для примера сервер меняет значения этих свойств и отправляет измененный объект обратно клиенту.
На веб-странице установим объект json для отправки и получим обратно данные с помощью метода respose.json():
fetch("/user", {
method: "POST",
headers: { "Accept": "application/json", "Content-Type": "application/json" },
body: JSON.stringify({
name: "Tom",
age: 37
})
})
.then(response => response.json())
.then(user => console.log(user.name, "-", user.age));