JavaScript · API · Начальный

Редиректы

5 задач

Разберитесь с HTTP-редиректами и управляйте тем, как fetch их обрабатывает.

Как работают HTTP-редиректы

#
HTTP-редирект — это ответ со статусом 3xx и заголовком `Location`, указывающим на новый URL. Ожидается, что клиент автоматически перейдёт по этому URL. `fetch` автоматически следует редиректам по умолчанию. Финальный URL после всех редиректов доступен через `response.url`: ```javascript const response = await fetch('https://apilearn.tukas.dev/api/redirect/'); console.log(response.url); // финальный URL после редиректов console.log(response.status); // статус финального ответа (например 200) ``` API имеет два эндпоинта с редиректом: ``` GET /api/redirect/ Редирект на /api/products/ GET /api/redirect/permanent/ Постоянный редирект (301) на /api/products/ ``` Чтобы запретить `fetch` следовать редиректам, установите `redirect: 'manual'`: ```javascript const response = await fetch('https://apilearn.tukas.dev/api/redirect/', { redirect: 'manual', }); // response.status равен 0, а response.type — 'opaqueredirect' в ручном режиме // response.url — URL редиректа в некоторых средах ``` Значения опции `redirect`: ``` "follow" (по умолчанию) Автоматически следовать всем редиректам "manual" Не следовать — остановиться на первом ответе с редиректом "error" Бросить ошибку при возникновении редиректа ```

Работа с редиректами на практике

#
Проверяем, куда ведёт редирект: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function checkRedirect(url) { const response = await fetch(url); console.log('Финальный URL:', response.url); console.log('Финальный статус:', response.status); console.log('OK:', response.ok); return response; } checkRedirect(`${BASE_URL}/api/redirect/`); ``` Определяем, был ли редирект, сравнивая исходный URL с `response.url`: ```javascript async function wasRedirected(url) { const response = await fetch(url); const redirected = response.url !== url; if (redirected) { console.log(`Перенаправлено с ${url} на ${response.url}`); } else { console.log('Редиректа не было'); } return response; } wasRedirected(`${BASE_URL}/api/redirect/`); ``` Проверяем ответ редиректа до перехода (Node.js / среды, которые это поддерживают): ```javascript const response = await fetch(`${BASE_URL}/api/redirect/`, { redirect: 'manual', }); console.log('Тип:', response.type); // "opaqueredirect" console.log('Статус:', response.status); // 0 в ручном режиме ```

Справочник редиректов

#
**Эндпоинты редиректов** ``` GET /api/redirect/ Временный редирект → /api/products/ GET /api/redirect/permanent/ Постоянный редирект (301) → /api/products/ ``` **Опция redirect в fetch** ```javascript fetch(url, { redirect: 'follow' }) // по умолчанию — следовать автоматически fetch(url, { redirect: 'manual' }) // остановиться на редиректе, без ошибки fetch(url, { redirect: 'error' }) // бросить TypeError при редиректе ``` **Определение редиректа** ```javascript const response = await fetch(url); const redirected = response.url !== url; // true, если редирект произошёл console.log(response.url); // финальный URL после редиректа ``` **Распространённые коды статуса редиректов** ``` 301 Moved Permanently — кешируйте новый URL 302 Found (Temporary) — не кешируйте 303 See Other — обычно после POST, редирект на GET 307 Temporary Redirect — аналог 302, но метод сохраняется 308 Permanent Redirect — аналог 301, но метод сохраняется ```
01

Следовать за редиректом

#

Получите `/api/redirect/`. Выведите `response.url` (финальный URL после редиректа) и `response.status`.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // fetch /api/redirect/ и вывести финальный URL и статус
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/redirect/`);
  console.log(response.url);
  console.log(response.status);
}

main();
02

Определить, был ли редирект

#

Получите `/api/redirect/` и сравните исходный URL с `response.url`. Выведите `true`, если редирект произошёл, `false` в противном случае.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const url = `${BASE_URL}/api/redirect/`;
  // fetch и сравнить url с response.url
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const url = `${BASE_URL}/api/redirect/`;
  const response = await fetch(url);
  console.log(response.url !== url);
}

main();
03

Сравнить временный и постоянный редирект

#

Получите `/api/redirect/` и `/api/redirect/permanent/`. Для каждого выведите финальный `response.url` и `response.status`.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // fetch оба эндпоинта и вывести финальный url + status для каждого
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const r1 = await fetch(`${BASE_URL}/api/redirect/`);
  console.log('Temporary:', r1.url, r1.status);

  const r2 = await fetch(`${BASE_URL}/api/redirect/permanent/`);
  console.log('Permanent:', r2.url, r2.status);
}

main();
04

Остановиться на редиректе в ручном режиме

#

Получите `/api/redirect/` с `redirect: "manual"`. Выведите `response.type` и `response.status`. Затем получите тот же URL со стандартным `redirect: "follow"` и сравните.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // ручной редирект
  // автоматический редирект
  // сравнить
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const manual = await fetch(`${BASE_URL}/api/redirect/`, { redirect: 'manual' });
  console.log('Manual — type:', manual.type, 'status:', manual.status);

  const follow = await fetch(`${BASE_URL}/api/redirect/`, { redirect: 'follow' });
  console.log('Follow — url:', follow.url, 'status:', follow.status);
}

main();
05

Получить данные через редирект

#

Получите `/api/redirect/` и разберите JSON-тело из финального ответа. Выведите `data.count`, чтобы подтвердить, что вы получили список товаров.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // fetch через редирект и прочитать тело ответа
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/redirect/`);
  const data = await response.json();
  console.log(data.count);
}

main();