JavaScript · API · Beginner

Redirects

5 tasks

Understand HTTP redirects and control how fetch handles them.

How HTTP redirects work

#
An HTTP redirect is a response with a 3xx status code and a `Location` header pointing to a new URL. The client is expected to follow that URL automatically. `fetch` follows redirects automatically by default. The final URL after all redirects is available on `response.url`: ```javascript const response = await fetch('https://apilearn.tukas.dev/api/redirect/'); console.log(response.url); // final URL after redirect(s) console.log(response.status); // status of the final response (e.g. 200) ``` The API has two redirect endpoints: ``` GET /api/redirect/ Redirects once to /api/products/ GET /api/redirect/permanent/ Permanent redirect (301) to /api/products/ ``` To prevent `fetch` from following redirects, set `redirect: 'manual'`: ```javascript const response = await fetch('https://apilearn.tukas.dev/api/redirect/', { redirect: 'manual', }); // response.status is 0 and response.type is 'opaqueredirect' for manual mode // response.url is the redirect location in some environments ``` The `redirect` option values: ``` "follow" (default) Follow all redirects automatically "manual" Don't follow — stop at the first redirect response "error" Throw an error if a redirect occurs ```

Working with redirects in practice

#
Check where a redirect leads: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function checkRedirect(url) { const response = await fetch(url); console.log('Final URL:', response.url); console.log('Final status:', response.status); console.log('OK:', response.ok); return response; } checkRedirect(`${BASE_URL}/api/redirect/`); ``` Detect that a redirect happened by comparing the original URL to `response.url`: ```javascript async function wasRedirected(url) { const response = await fetch(url); const redirected = response.url !== url; if (redirected) { console.log(`Redirected from ${url} to ${response.url}`); } else { console.log('No redirect'); } return response; } wasRedirected(`${BASE_URL}/api/redirect/`); ``` Inspect the redirect response before following (Node.js / environments that support it): ```javascript const response = await fetch(`${BASE_URL}/api/redirect/`, { redirect: 'manual', }); console.log('Type:', response.type); // "opaqueredirect" console.log('Status:', response.status); // 0 in manual mode ```

Redirect reference

#
**Redirect endpoints** ``` GET /api/redirect/ Temporary redirect → /api/products/ GET /api/redirect/permanent/ Permanent redirect (301) → /api/products/ ``` **fetch redirect option** ```javascript fetch(url, { redirect: 'follow' }) // default — follow automatically fetch(url, { redirect: 'manual' }) // stop at redirect, no throw fetch(url, { redirect: 'error' }) // throw TypeError on redirect ``` **Detect redirect** ```javascript const response = await fetch(url); const redirected = response.url !== url; // true if redirect happened console.log(response.url); // final URL after redirect ``` **Common redirect status codes** ``` 301 Moved Permanently — cache the new URL 302 Found (Temporary) — don't cache 303 See Other — usually after POST, redirect to GET 307 Temporary Redirect — same as 302 but method preserved 308 Permanent Redirect — same as 301 but method preserved ```
01

Follow a redirect

#

Fetch `/api/redirect/`. Print `response.url` (the final URL after redirect) and `response.status`.

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

async function main() {
  // fetch /api/redirect/ and print final URL and status
}

main();
Solution
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

Detect if a redirect happened

#

Fetch `/api/redirect/` and compare the original URL to `response.url`. Print `true` if a redirect happened, `false` otherwise.

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

async function main() {
  const url = `${BASE_URL}/api/redirect/`;
  // fetch and compare url vs response.url
}

main();
Solution
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

Compare temporary and permanent redirect

#

Fetch both `/api/redirect/` and `/api/redirect/permanent/`. For each, print the final `response.url` and `response.status`.

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

async function main() {
  // fetch both endpoints and print final url + status for each
}

main();
Solution
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

Stop at redirect with manual mode

#

Fetch `/api/redirect/` with `redirect: "manual"`. Print `response.type` and `response.status`. Then fetch the same URL with the default `redirect: "follow"` and compare.

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

async function main() {
  // manual redirect
  // follow redirect
  // compare
}

main();
Solution
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

Fetch data through a redirect

#

Fetch `/api/redirect/` and parse the JSON body from the final response. Print `data.count` to confirm you got the products list.

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

async function main() {
  // fetch through redirect and read the response body
}

main();
Solution
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();