Станом на зараз ми вже дещо знаємо про fetch.
Розгляньмо решту API, щоб охопити всі його можливості.
Зверніть увагу: більшість з цих опцій використовуються рідко. Ви можете пропустити цей розділ і все одно без проблем користуватися fetch.
Тим не менш, корисно знати, що може робити fetch, тому якщо виникне така необхідність, завжди можна повернутись до цієї статті і розібратись детальніше.
Ось повний список всіх можливих опцій fetch з їх типовими значеннями (альтернативи в коментарях):
let promise = fetch(url, {
method: "GET", // POST, PUT, DELETE та інші
headers: {
// значення цього заголовку зазвичай встановлюється автоматично,
// залежно від тіла запиту
"Content-Type": "text/plain;charset=UTF-8"
},
body: undefined // string, FormData, Blob, BufferSource або URLSearchParams
referrer: "about:client", // або "", щоб не посилати заголовок Referer,
// або URL з поточного джерела
referrerPolicy: "strict-origin-when-cross-origin", // no-referrer-when-downgrade, no-referrer, origin, same-origin...
mode: "cors", // same-origin, no-cors
credentials: "same-origin", // omit, include
cache: "default", // no-store, reload, no-cache, force-cache або only-if-cached
redirect: "follow", // manual, error
integrity: "", // контрольна сума, наприклад "sha256-abcdef1234567890"
keepalive: false, // true
signal: undefined, // AbortController, щоб перервати запит
window: window // null
});
Перелік вражає, чи не так?
Ми повністю висвітлили method, headers та body у главі Fetch.
Опція signal висвітлена у главі Fetch: Переривання.
Тепер розгляньмо решту можливостей.
referrer, referrerPolicy
Ці опції вказують, як fetch встановлює HTTP-заголовок Referer.
Зазвичай цей заголовок встановлюється автоматично і містить адресу сторінки, з якої був зроблений запит. У більшості сценаріїв він взагалі не важливий, іноді, з метою безпеки, є сенс видалити або скоротити його.
Опція referrer дозволяє задати будь-який Referer (в межах поточного джерела) або видалити його..
Щоб не надсилати Referer, задайте порожній рядок:
fetch('/page', {
referrer: "" // немає заголовку Referer
});
Щоб встановити іншу URL-адресу в межах поточного джерела:
fetch('/page', {
// припускаючи, що ми на сторінці https://javascript.info
// ми можемо задати будь-який заголовок Referer, але тільки в межах поточного джерела
referrer: "https://javascript.info/anotherpage"
});
Опція referrerPolicy задає загальні правила для Referer..
Запити поділяються на 3 типи:
- Запит на те ж джерело.
- Запит на інше джерело.
- Запит з HTTPS на HTTP (з безпечного на небезпечний протокол).
На відміну від опції referrer, яка дозволяє задати конкретне значення Referer, referrerPolicy вказує браузеру загальні правила для кожного типу запиту.
Можливі значення описані у Referrer Policy specification:
"strict-origin-when-cross-origin"– для запитів до однакового джерела надсилати повнийReferer, для запитів між різними джерелами надсилати лише джерело, якщо це не HTTPS→HTTP запит, тоді нічого не надсилати."no-referrer-when-downgrade"– типове значення: повнийRefererнадсилається завжди, хіба що ми не надсилаємо запит із HTTPS на HTTP (на менш безпечний протокол)."no-referrer"– ніколи не надсилатиReferer."origin"– надсилати лише джерело вReferer, а не повну URL-адресу сторінки, наприклад лишеhttp://site.comзамістьhttp://site.com/path."origin-when-cross-origin"– надсилати повнийRefererдля запитів до однакового джерела, але лише частину джерела для запитів між різними джерелами (як показано вище)."same-origin"– надсилати повнийRefererдля запитів до однакового джерела, але безRefererдля запитів між різними джерелами."strict-origin"– надсилати лише джерело, а неRefererдля HTTPS→HTTP запитів."unsafe-url"– завжди надсилати повну URL-адресу вReferer, навіть для HTTPS→HTTP запитів.
Ось таблиця зі всіма комбінаціями:
| Значення | До того ж джерела | До іншого джерела | HTTPS→HTTP |
|---|---|---|---|
"no-referrer" |
- | - | - |
"no-referrer-when-downgrade" |
full | full | - |
"origin" |
origin | origin | origin |
"origin-when-cross-origin" |
full | origin | origin |
"same-origin" |
full | - | - |
"strict-origin" |
origin | origin | - |
"strict-origin-when-cross-origin" або "" (типове значення) |
full | origin | - |
"unsafe-url" |
full | full | full |
Припустімо, у нас є зона адміністрування зі структурою URL-адреси, яка не повинна бути відома за межами сайту.
Якщо ми надсилаємо fetch, то типово він завжди надсилає заголовок Referer із повною URL-адресою нашої сторінки (окрім випадків, коли ми надсилаємо запит із HTTPS на HTTP, тоді без Referer).
Наприклад, Referer: https://javascript.info/admin/secret/paths.
Якщо ми хочемо, щоб інші веб-сайти знали лише джерело, а не URL-шлях, ми можемо задати опцію:
fetch('https://another.com/page', {
// ...
referrerPolicy: "origin-when-cross-origin" // Referer: https://javascript.info
});
Ми можемо додавати його до всіх викликів fetch, навіть інтегрувати в JavaScript бібліотеку нашого проекту, яка відповідає за запити та використовує fetch всередині.
Його єдина відмінність у порівнянні з типовою поведінкою полягає в тому, що для запитів до іншого джерела fetch надсилає лише вихідну частину URL-адреси (наприклад, https://javascript.info, без шляху). Для запитів до нашого джерела ми все ще отримуємо повний Referer (може бути корисним для задач з налагодження).
fetchПолітика встановлення Referrer, що описана у специфікації, стосується не лише fetch, а є більш глобальною.
Зокрема, можна встановити типову політику для всієї сторінки за допомогою HTTP-заголовка Referrer-Policy або окремого посилання за допомогою <a rel="noreferrer">.
mode
Опція mode є засобом безпеки, що запобігає випадковим запитам між різними джерелами:
"cors"– запити між різними джерелами типово дозволені, як описано в Fetch: Запити між різними джерелами,"same-origin"– запити між різними джерелами заборонені,"no-cors"– дозволені лише безпечні запити між різними джерелами.
Ця опція може бути корисною, якщо URL-адреса для fetch надходить від третьої сторони, і ми хочемо, щоб “глобальний перемикач” обмежував можливість запитів між різними джерелами.
credentials
Опція credentials визначає, чи має fetch надсилати файли cookie та заголовки HTTP-Authorization разом із запитом.
"same-origin"– типове значення, не надсилати запити між різними джерелами,"include"– завжди надсилати, вимагаєAccess-Control-Allow-Credentialsвід сервера іншого джерела, щоб JavaScript міг отримати доступ до відповіді, про що йдеться у главі Fetch: Запити між різними джерелами,"omit"– ніколи не надсилати, навіть для запитів з однаковим джерелом.
cache
Типово запити fetch використовують стандартне HTTP-кешування. Тобто він визнає заголовки Expires і Cache-Control, надсилає If-Modified-Since і т.д. Так само як роблять звичайні HTTP-запити.
Опції cache дозволяють ігнорувати HTTP-кеш або тонко налаштувати його використання:
"default"–fetchвикористовує стандартні правила HTTP-кешу та заголовки,"no-store"– повністю ігнорувати HTTP-кеш, цей режим стане типовим, якщо ми встановимо заголовокIf-Modified-Since,If-None-Match,If-Unmodified -Since,If-MatchабоIf-Range,"reload"– не брати результат із HTTP-кешу (якщо є), а заповнити кеш відповіддю (якщо заголовки відповіді дозволяють цю дію),"no-cache"– створити умовний запит, якщо є кешована відповідь, і звичайний запит в іншому випадку. Заповнити HTTP-кеш відповіддю,"force-cache"– використовувати відповідь з HTTP-кешу, навіть якщо він застарілий. Якщо в HTTP-кеші немає відповіді, зробити звичайний HTTP-запит, поводитися як зазвичай,"only-if-cached"– використовувати відповідь з HTTP-кешу, навіть якщо він застарілий. Якщо в HTTP-кеші немає відповіді, то видати помилку. Працює лише тоді, колиmodeмає значення"same-origin".
redirect
Зазвичай fetch прозоро слідує HTTP-переадресаціям, таким як 301, 302 тощо.
Опція redirect дозволяє змінити це:
"follow"– типове значення, слідувати HTTP-переадресаціям,"error"– помилка при HTTP-переадресації,"manual"– дозволяє обробляти HTTP-переадресації вручну. У разі переадресації ми отримаємо спеціальний об’єкт відповіді зresponse.type="opaqueredirect"та нульовим/порожнім статусом і більшістю інших властивостей.
integrity
Опція integrity дозволяє перевірити, чи відповідає відповідь контрольній сумі відомій наперед.
Як описано в специфікації, хеш-функціями, що підтримуються, є SHA-256, SHA-384 і SHA-512, залежно від браузера.
Наприклад, ми завантажуємо файл і знаємо, що його контрольна сума SHA-256 дорівнює “abcdef” (справжня контрольна сума, звичайно, довша).
Ми можемо розмістити його в опції integrity, наприклад:
fetch('http://site.com/file', {
integrity: 'sha256-abcdef'
});
Далі fetch самостійно обчислить SHA-256 і порівняє його з нашим рядком. У разі розбіжності буде згенерована помилка.
keepalive
Опція keepalive вказує на те, що запит має “пережити” веб-сторінку, яка його ініціювала.
Наприклад, ми збираємо статистику про те, як поточний відвідувач використовує нашу сторінку (кліки миші, фрагменти сторінки, які він переглядає), для аналізу і поліпшення користувацького досвіду.
Коли відвідувач залишає нашу сторінку – ми хотіли б зберегти дані на нашому сервері.
Для цього ми можемо використовувати подію window.onunload:
window.onunload = function() {
fetch('/analytics', {
method: 'POST',
body: "statistics",
keepalive: true
});
};
Зазвичай, коли документ вивантажується, всі пов’язані з ним мережеві запити перериваються. Але опція keepalive говорить браузеру виконувати запит у фоновому режимі, навіть після того, як він залишить сторінку. Отже, ця опція необхідна для успішного виконання нашого запиту.
Вона має кілька обмежень:
- Ми не можемо відправляти мегабайти: ліміт тіла для запитів
keepaliveстановить 64КБ.- Якщо нам потрібно зібрати багато статистики про відвідування, ми повинні надсилати її регулярно пакетами, щоб на останній запит
onunloadне залишилося багато. - Це обмеження стосується всіх
keepalive-запитів разом. Іншими словами, ми можемо паралельно виконувати декілька запитівkeepalive, але сума довжин їхніх тіл не повинна перевищувати 64КБ.
- Якщо нам потрібно зібрати багато статистики про відвідування, ми повинні надсилати її регулярно пакетами, щоб на останній запит
- Ми не зможемо обробити відповідь сервера, якщо документ буде вивантажений. Тому в нашому прикладі
fetchпройде успішно завдякиkeepalive, але наступні функції не працюватимуть.- У більшості випадків, наприклад, при розсилці статистики, це не є проблемою, оскільки сервер просто приймає дані та зазвичай на такі запити відправляє порожню відповідь.
Коментарі
<code>, для кількох рядків – обгорніть їх тегом<pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)