JavaRush /Курсы /Модуль 1: Web Core /Fetch API: базовый пример запроса данных, практика

Fetch API: базовый пример запроса данных, практика

Модуль 1: Web Core
23 уровень , 9 лекция
Открыта

1. Для чего нужен Fetch API

Fetch API — это современный стандартный способ отправлять HTTP-запросы из JavaScript. Он позволяет получать (и отправлять) данные с сервера прямо из браузера, без необходимости перезагружать страницу. Это основа для работы с REST API, загрузки данных для SPA (Single Page Application), подгрузки контента “на лету” и многих других фишек современных сайтов.

Аналогия:
Представьте, что ваш сайт — это ресторан, а сервер — кухня. Когда посетитель (пользователь) заказывает блюдо (например, список новостей), официант (JavaScript) отправляет заказ (HTTP-запрос) на кухню (сервер) и через некоторое время приносит результат (ответ сервера). Fetch API — это как универсальный официант, который может передавать любые заказы на кухню и возвращать любые блюда.

Базовый синтаксис

Давайте сразу к делу. Вот минимальный пример запроса с помощью Fetch API:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  });

Как это работает?

  1. fetch(url) — отправляет GET-запрос по нужному адресу. Возвращает специальный объект — Promise (обещание).
  2. response.json() — преобразует “сырые” данные ответа в объект JavaScript (если это был JSON).
  3. .then(data => ...) — здесь мы получаем уже готовые данные и можем с ними что-то делать.

Вывод:
В консоли появится объект:

{
  userId: 1,
  id: 1,
  title: "delectus aut autem",
  completed: false
}

Почему fetch возвращает Promise?

Потому что запрос на сервер — это не мгновенная операция. Данные могут прийти через секунду, а могут и через 10 секунд (если сервер ушёл пить чай). Promise позволяет нам “подписаться” на результат и продолжить работу, не блокируя страницу.

2. Практика: получаем данные и показываем их на странице

Давайте усложним пример и выведем полученные данные не только в консоль, но и на страницу. Для этого будем использовать уже знакомые нам методы работы с DOM.

Задача: вывести заголовок задачи из API

HTML-разметка:

<div id="todo"></div>
<button id="loadTodo">Загрузить задачу</button>

JS-код:

const todoDiv = document.getElementById('todo');
const btn = document.getElementById('loadTodo');

btn.addEventListener('click', () => {
  todoDiv.textContent = 'Загрузка...';

  fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => response.json())
    .then(data => {
      // Выводим заголовок задачи
      todoDiv.textContent = `Задача: ${data.title} (выполнена: ${data.completed ? 'да' : 'нет'})`;
    })
    .catch(error => {
      todoDiv.textContent = 'Ошибка загрузки данных!';
      console.error(error);
    });
});

Что происходит:

  • При нажатии на кнопку появляется “Загрузка...”
  • JS отправляет запрос на сервер.
  • Как только данные приходят, мы обновляем содержимое блока todoDiv.
  • Если что-то пошло не так (например, сервер упал под тяжестью ваших запросов), выводим сообщение об ошибке.

3. fetch: GET, POST и другие методы

По умолчанию fetch(url) делает GET-запрос (получить данные). Но иногда нам нужно отправить данные на сервер (например, форму). Для этого у fetch есть второй аргумент — объект с настройками.

Пример POST-запроса

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST', // Говорим, что хотим отправить данные
  headers: {
    'Content-Type': 'application/json' // Тип данных, которые мы отправляем
  },
  body: JSON.stringify({
    title: 'Hello World',
    body: 'Это мой первый пост через fetch!',
    userId: 1
  })
})
  .then(response => response.json())
  .then(data => {
    console.log('Ответ сервера:', data);
  });

Что важно:

  • method: 'POST' — тип запроса.
  • headers — заголовки (например, чтобы сервер понял, что мы отправляем JSON).
  • body — тело запроса, обычно строка в формате JSON.

4. Асинхронность и обработка ошибок

Fetch — это всегда асинхронно. Код после вызова fetch не ждёт ответа, а продолжает выполняться. Поэтому все действия с результатом нужно делать только внутри .then() или с помощью async/await (о чём подробнее будет позже).

Обработка ошибок

Fetch не бросает ошибку, если сервер вернул 404 или 500 — только если запрос “физически” не удался (например, нет интернета). Чтобы обработать ошибки с кодом ответа, нужно проверить свойство response.ok.

Пример:

fetch('https://jsonplaceholder.typicode.com/todos/101010101') // такого нет
  .then(response => {
    if (!response.ok) {
      throw new Error('Сервер вернул ошибку: ' + response.status);
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('Ошибка запроса:', error.message);
  });

5. Практика: загружаем и показываем список задач

Давайте добавим интерактива в наше мини-приложение: будем загружать массив задач и выводить их список на страницу.

HTML:

<div id="todos"></div>
<button id="loadTodos">Показать список задач</button>

JS:

const todosDiv = document.getElementById('todos');
const btnTodos = document.getElementById('loadTodos');

btnTodos.addEventListener('click', () => {
  todosDiv.textContent = 'Загрузка...';

  fetch('https://jsonplaceholder.typicode.com/todos?_limit=5')
    .then(response => response.json())
    .then(todos => {
      // Очищаем div
      todosDiv.innerHTML = '';
      // Создаём список
      const ul = document.createElement('ul');
      todos.forEach(todo => {
        const li = document.createElement('li');
        li.textContent = `${todo.title} (${todo.completed ? '✓' : '✗'})`;
        ul.appendChild(li);
      });
      todosDiv.appendChild(ul);
    })
    .catch(error => {
      todosDiv.textContent = 'Ошибка загрузки!';
      console.error(error);
    });
});

Что происходит:

  • При клике загружаем 5 задач.
  • Для каждой задачи создаём элемент списка (li).
  • Добавляем их в ul, который отображается на странице.
  • Если что-то пошло не так — показываем ошибку.

6. fetch и формы: отправляем данные пользователя

Рассмотрим, как отправить данные с формы на сервер с помощью fetch.

HTML:

<form id="postForm">
  <input type="text" name="title" placeholder="Заголовок" required />
  <input type="text" name="body" placeholder="Текст" required />
  <button type="submit">Отправить</button>
</form>
<div id="result"></div>

JS:

const form = document.getElementById('postForm');
const resultDiv = document.getElementById('result');

form.addEventListener('submit', function(event) {
  event.preventDefault(); // Не даём форме перезагрузить страницу

  const formData = new FormData(form);
  const data = {
    title: formData.get('title'),
    body: formData.get('body'),
    userId: 1
  };

  fetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
  })
    .then(response => response.json())
    .then(post => {
      resultDiv.textContent = `Пост создан с id: ${post.id}`;
    })
    .catch(error => {
      resultDiv.textContent = 'Ошибка при отправке!';
      console.error(error);
    });
});

Что происходит:

  • Перехватываем отправку формы.
  • Собираем данные из полей.
  • Отправляем их на сервер.
  • Показываем результат пользователю.

7. fetch и JSON: что внутри ответа

Большинство современных API возвращают данные в формате JSON (JavaScript Object Notation). Это просто текст, который очень похож на объекты JavaScript.

Как получить объект из ответа?
Используйте response.json(). Это тоже возвращает Promise, потому что иногда браузеру нужно “дожевать” большие данные.

Внимание:
Если вы попытаетесь использовать данные до того, как они загрузились — получите “обещание”, а не сами данные.

Пример неправильного кода:

const data = fetch('https://jsonplaceholder.typicode.com/todos/1').then(r => r.json());
console.log(data); // Выведет Promise, а не объект!

Правильно:

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(r => r.json())
  .then(data => {
    console.log(data); // Вот теперь это объект!
  });

8. Типичные ошибки при работе с Fetch API

Ошибка №1: Пытаться работать с результатом fetch вне .then()

Многие новички ожидают, что fetch вернёт “готовые” данные, но на самом деле он возвращает Promise. Если вы попытаетесь сразу использовать результат, получите не данные, а “обещание”.

Ошибка №2: Забыть про .json()

Ответ сервера — это не сразу объект, а специальный Response. Чтобы получить данные, нужно вызвать .json() (или .text(), если сервер возвращает обычный текст).

Ошибка №3: Не обрабатывать ошибки

Если не добавить обработчик .catch(), ошибки запроса останутся незамеченными. В реальных приложениях это может привести к “молчаливым” багам.

Ошибка №4: Не проверить response.ok

fetch не считает ошибкой ответ сервера с кодом 404 или 500. Если не проверить response.ok, вы можете получить неожиданные данные или пустоту.

Ошибка №5: Проблемы с CORS

Если сервер не разрешает запросы с вашего сайта, fetch завершится с ошибкой CORS. Это не баг вашего кода, а вопрос политики безопасности.

Ошибка №6: Забыть про асинхронность

fetch всегда асинхронен. Не пытайтесь использовать результат fetch сразу после вызова — работайте с ним только внутри .then() или с помощью async/await.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ