Функция 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));