На цей момент ми вже детально розглянули основи Fetch API: базові запити, FormData, відстеження прогресу, переривання та CORS. Але Fetch API має набагато більше можливостей через додаткові опції конфігурації.
Важливо: Більшість цих опцій використовуються рідко і потрібні лише для спеціалізованих сценаріїв. Ви можете успішно працювати з fetch, знаючи лише базові опції. Цей розділ — довідник для особливих випадків.
Ось всі можливі опції з їх значеннями за замовчуванням:
const response = await fetch(url, {
// Основні опції (розглянуті раніше)
method: 'GET', // POST, PUT, DELETE, PATCH
headers: {}, // об'єкт або Headers
body: undefined, // string, FormData, Blob, URLSearchParams
signal: undefined, // AbortController.signal
// Безпека та CORS
mode: 'cors', // 'same-origin', 'no-cors'
credentials: 'same-origin', // 'omit', 'include'
// Referer
referrer: 'about:client', // '' (не відправляти) або URL
referrerPolicy: 'strict-origin-when-cross-origin',
// Кешування
cache: 'default', // 'no-store', 'reload', 'no-cache', etc.
// Переадресація
redirect: 'follow', // 'error', 'manual'
// Валідація цілісності
integrity: '', // наприклад, 'sha256-abc123...'
// Keepalive
keepalive: false, // true для аналітики
// Застарілі/рідковживані
window: window, // null
})
GET, POST, PUT, DELETE, PATCHHeadersstring, FormData, Blob, URLSearchParamsAbortController для перериванняReferer (так, з помилкою в назві) — HTTP header, який містить URL сторінки, з якої був зроблений запит.
GET /api/data HTTP/1.1
Host: api.example.com
Referer: https://mysite.com/admin/dashboard
Навіщо? Сервер бачить, звідки прийшов запит (для аналітики, безпеки).
Проблема: Може розкривати чутливу інформацію з URL (наприклад, /admin/secret-page).
referrerДозволяє встановити або приховати Referer:
// Не відправляти Referer взагалі
fetch('/api/data', {
referrer: '',
})
// Встановити власне значення (в межах того самого origin)
fetch('/api/data', {
referrer: 'https://mysite.com/public-page',
})
referrer тільки на URL вашого власного origin. Неможливо підробити Referer на чужий домен.// ✅ Можна (той самий origin)
fetch('/api', { referrer: 'https://mysite.com/page' })
// ❌ Буде ігноровано (інший origin)
fetch('/api', { referrer: 'https://evil.com' })
referrerPolicyВстановлює загальні правила для Referer header:
| Policy | Same-Origin | Cross-Origin | HTTPS→HTTP |
|---|---|---|---|
no-referrer | — | — | — |
no-referrer-when-downgrade | Full URL | Full URL | — |
origin | Origin only | Origin only | Origin only |
origin-when-cross-origin | Full URL | Origin only | Origin only |
same-origin | Full URL | — | — |
strict-origin | Origin only | Origin only | — |
strict-origin-when-cross-origin ⭐ | Full URL | Origin only | — |
unsafe-url | Full URL | Full URL | Full URL |
⭐ Значення за замовчуванням
Пояснення значень:
https://site.com/admin/dashboardhttps://site.comПриклад: приховування шляху від зовнішніх сайтів
// Для cross-origin відправляємо лише origin, без шляху
fetch('https://external-api.com/data', {
referrerPolicy: 'origin-when-cross-origin',
})
// Referer буде: https://mysite.com (без /admin/secret)
Приклад: повна приватність
// Ніколи не відправляти Referer
fetch('/api/data', {
referrerPolicy: 'no-referrer',
})
Опція mode контролює, чи дозволені cross-origin запити:
fetch(url, {
mode: 'cors' | 'same-origin' | 'no-cors',
})
'cors' (за замовчуванням)
Дозволяє cross-origin запити з CORS headers:
fetch('https://api.github.com/users/octocat', {
mode: 'cors', // дозволено
})
'same-origin'
Заборонює будь-які cross-origin запити:
fetch('https://external-api.com/data', {
mode: 'same-origin',
})
// ❌ TypeError: Failed to fetch
'no-cors'
Дозволяє лише "безпечні" cross-origin запити БЕЗ доступу до відповіді:
const response = await fetch('https://example.com/image.jpg', {
mode: 'no-cors',
})
console.log(response.status) // 0
console.log(await response.text()) // Помилка - доступ заборонено!
no-cors - не те, що ви думаєтеБагато розробників помилково використовують mode: 'no-cors', думаючи, що це "вимкне CORS". Насправді це робить відповідь opaque (непрозорою) — ви не можете прочитати дані!✅ Використовуйте no-cors лише для:Контролює відправку cookies та HTTP Authentication:
fetch(url, {
credentials: 'same-origin' | 'include' | 'omit',
})
'same-origin' (за замовчуванням)
Cookies відправляються лише для same-origin запитів:
// ✅ Cookies відправляються
fetch('/api/profile')
// ❌ Cookies НЕ відправляються
fetch('https://external-api.com/data')
'include'
Завжди відправляти cookies (навіть cross-origin):
fetch('https://api.mybackend.com/profile', {
credentials: 'include',
})
Сервер має відповісти:
Access-Control-Allow-Origin: https://mysite.com
Access-Control-Allow-Credentials: true
'omit'
Ніколи не відправляти cookies (навіть same-origin):
fetch('/api/public-data', {
credentials: 'omit', // Без cookies
})
async function getUUserProfile() {
const response = await fetch('https://api.myapp.com/user/profile', {
credentials: 'include', // Відправити session cookie
headers: {
Accept: 'application/json',
},
})
if (!response.ok) {
throw new Error('Not authenticated')
}
return response.json()
}
Керує взаємодією з HTTP-кешем браузера:
fetch(url, {
cache: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached',
})
| Режим | Опис | Коли використовувати |
|---|---|---|
default | Стандартне HTTP кешування | 99% випадків |
no-store | Не кешувати запит і відповідь | Чутливі дані |
reload | Ігнорувати кеш, але оновити його | "Примусове оновлення" |
no-cache | Валідувати кеш, потім використати | Актуальні дані |
force-cache | Використати кеш (навіть застарілий) | Офлайн режим |
only-if-cached | Тільки кеш, помилка якщо немає | Повний офлайн |
Завжди свіжі дані (без кешу)
fetch('/api/stock-prices', {
cache: 'no-store', // Ніколи не кешувати
})
Примусове оновлення (hard reload)
fetch('/api/config', {
cache: 'reload', // Ігнорувати кеш, оновити його
})
Офлайн-режим (використовувати кеш)
fetch('/api/articles', {
cache: 'force-cache', // Використати кеш, навіть якщо застарілий
}).catch(() => {
console.log('Немає інтернету, використано кеш')
})
Контролює обробку HTTP redirects (301, 302, 307, 308):
fetch(url, {
redirect: 'follow' | 'error' | 'manual',
})
'follow' (за замовчуванням)
Автоматично слідувати redirects:
fetch('http://example.com/old-url', {
redirect: 'follow',
})
// Автоматично перейде на новий URL
'error'
Генерувати помилку при redirect:
fetch('http://example.com/old-url', {
redirect: 'error',
})
// TypeError: Failed to fetch (якщо є redirect)
'manual'
Дозволяє обробляти redirects вручну:
const response = await fetch('http://example.com/old-url', {
redirect: 'manual',
})
if (response.type === 'opaqueredirect') {
console.log('Redirect виявлено, але не обробленосправжнього статусу немає')
// response.status === 0
// response.url === ''
}
manual?Рідко потрібно. Може бути корисно для:Валідує, що завантажений ресурс відповідає очікуваній контрольній сумі (hash):
fetch(url, {
integrity: 'sha256-{hash}' | 'sha384-{hash}' | 'sha512-{hash}',
})
integrity// Завантажуємо jQuery з CDN з перевіркою integrity
fetch('https://code.jquery.com/jquery-3.7.1.min.js', {
integrity: 'sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=',
})
.then((r) => r.text())
.then((code) => {
console.log('jQuery завантажено та перевірено!')
eval(code) // Безпечно, бо перевірили hash
})
.catch((error) => {
console.error('Hash не збігається! Можлива модифікація файлу.')
})
Онлайн: Використовуйте SRI Hash Generator
Командний рядок:
# Для файлу
curl https://code.jquery.com/jquery-3.7.1.min.js | openssl dgst -sha256 -binary | openssl base64 -A
# Результат: sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=
integrity — це реалізація SRI специфікації. Це особливо важливо для:Дозволяє запиту "пережити" закриття сторінки:
fetch(url, {
keepalive: true,
})
Коли користувач закриває вкладку, браузер скасовує всі активні запити:
window.addEventListener('unload', () => {
fetch('/analytics', {
method: 'POST',
body: JSON.stringify({ event: 'page_close' }),
})
// ❌ Запит буде скасовано!
})
window.addEventListener('unload', () => {
fetch('/analytics', {
method: 'POST',
body: JSON.stringify({ event: 'page_close' }),
keepalive: true, // ✅ Запит завершиться навіть після закриття
})
})
class Analytics {
constructor() {
this.events = []
// Відправляти при закритті сторінки
window.addEventListener('beforeunload', () => {
this.flush()
})
// Або кожні 30 секунд
setInterval(() => this.flush(), 30000)
}
track(eventName, data) {
this.events.push({
event: eventName,
data,
timestamp: Date.now(),
})
// Якщо багато подій, відправити зараз
if (this.events.length >= 10) {
this.flush()
}
}
flush() {
if (this.events.length === 0) return
const payload = JSON.stringify(this.events)
// Перевірка ліміту 64KB
if (new Blob([payload]).size > 64 * 1024) {
console.warn('Payload занадто великий для keepalive')
return
}
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: payload,
keepalive: true,
})
this.events = []
}
}
// Використання
const analytics = new Analytics()
analytics.track('page_view', { url: location.href })
analytics.track('button_click', { button: 'signup' })
navigator.sendBeacon():window.addEventListener('beforeunload', () => {
const data = JSON.stringify({ event: 'page_close' })
navigator.sendBeacon('/analytics', data)
})
Fetch API має багато опцій для тонкого налаштування:
Referrer Control
{
referrer: '', // Приховати
referrerPolicy: 'no-referrer'
}
✅ Для приватності та безпеки ✅ Приховання внутрішньої структури URL
Security & CORS
{
mode: 'same-origin',
credentials: 'include'
}
✅ Контроль cross-origin запитів ✅ Керування cookies
Caching
{
cache: 'no-store', // no cache
cache: 'reload', // обійти кеш
cache: 'force-cache' // offline
}
✅ Контроль свіжості даних ✅ Офлайн режим
Integrity & Keepalive
{
integrity: 'sha256-abc...',
keepalive: true
}
✅ Валідація файлів з CDN ✅ Аналітика при закритті
| Опція | Значення за замовчуванням | Основні альтернативи |
|---|---|---|
method | 'GET' | POST, PUT, DELETE, PATCH |
headers | {} | Об'єкт або Headers instance |
body | undefined | string, FormData, Blob |
mode | 'cors' | 'same-origin', 'no-cors' |
credentials | 'same-origin' | 'include', 'omit' |
cache | 'default' | 'no-store', 'reload', 'no-cache' |
redirect | 'follow' | 'error', 'manual' |
referrer | 'about:client' | '' (не відправляти), URL |
referrerPolicy | 'strict-origin-when-cross-origin' | 'no-referrer', 'origin' |
integrity | '' | 'sha256-...', 'sha384-...' |
keepalive | false | true |
signal | undefined | AbortController.signal |
✅ referrerPolicy:
✅ cache: 'no-store':
✅ integrity:
✅ keepalive:
❌ Не використовувати без потреби:
mode: 'no-cors' (майже ніколи не потрібен)redirect: 'manual' (складна обробка)force-cache)Більшість проектів чудово працюють з базовими опціями (method, headers, body, signal). Використовуйте розширені опції лише коли є конкретна потреба, а не "на всяк випадок".
CORS - Запити між різними джерелами
Розберіть механізм CORS, safe та unsafe запити, preflight перевірки, credentials та налаштування сервера для cross-origin запитів
URL Objects - Робота з посиланнями
Навіщо потрібен клас URL, як розбирати адреси на частини, керувати query-параметрами через URLSearchParams та правильно кодувати символи