← Назад к вопросам

Как получить JSON из fetch запроса?

1.3 Junior🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как получить JSON из fetch запроса

Fetch API возвращает Response объект, а не сразу данные. Для получения JSON нужно вызвать метод .json().

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

fetch("https://api.example.com/users")
  .then(response => response.json()) // Парсим JSON
  .then(data => console.log(data)); // Используем данные

Подробный разбор

Шаг 1: Fetch возвращает Promise<Response>

const fetchPromise = fetch("https://api.example.com/users");
console.log(fetchPromise); // Promise { <pending> }

Fetch создаёт Promise, который разрешится, когда ответ начнёт приходить (не когда завершится полностью).

Шаг 2: Response содержит метаданные и методы

fetch("https://api.example.com/users")
  .then(response => {
    // response — это Response объект
    console.log(response.status); // 200
    console.log(response.statusText); // "OK"
    console.log(response.headers); // Headers {...}
    console.log(response.ok); // true (200-299)
    
    // Тело ещё не парсено!
    return response.json();
  });

Шаг 3: Парсинг JSON методом .json()

fetch("https://api.example.com/users")
  .then(response => response.json()) // Преобразуй body в JSON
  .then(data => {
    // data — это уже распарсенный объект JavaScript
    console.log(data); // { id: 1, name: "John", ... }
    console.log(typeof data); // "object"
  });

Ключевое отличие:

  • response.json() — асинхронная операция, возвращает Promise
  • Она парсит текст из тела ответа в объект JavaScript

Полный пример с обработкой ошибок

fetch("https://api.example.com/users")
  .then(response => {
    // Проверяем статус
    if (!response.ok) {
      throw new Error(`HTTP ошибка! Статус: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log("Данные получены:", data);
  })
  .catch(error => {
    console.error("Ошибка:", error);
  });

Async/Await (более читаемо)

async function fetchUsers() {
  try {
    const response = await fetch("https://api.example.com/users");
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    
    const data = await response.json(); // Ждём парсинга JSON
    console.log(data);
    return data;
  } catch (error) {
    console.error("Ошибка:", error);
  }
}

fetchUsers();

Другие методы парсинга

Response объект имеет несколько методов для разных форматов:

const response = await fetch(url);

// JSON
const json = await response.json();

// Простой текст
const text = await response.text();

// Blob (для файлов)
const blob = await response.blob();

// ArrayBuffer (для бинарных данных)
const buffer = await response.arrayBuffer();

// FormData
const formData = await response.formData();

// Клон тела (для повторного парсинга)
const clone = response.clone();
const json = await clone.json();

Важно: каждый метод парсинга можно вызвать только один раз. Body стрим может быть прочитан один раз:

// ❌ Ошибка
const response = await fetch(url);
const text = await response.text();
const json = await response.json(); // Ошибка! Body уже прочитан

// ✅ Правильно
const response = await fetch(url);
const json = await response.json();

React Hook: Получение JSON

function UsersList() {
  const [users, setUsers] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    fetch("https://api.example.com/users")
      .then(response => {
        if (!response.ok) throw new Error("Network response");
        return response.json();
      })
      .then(data => {
        setUsers(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, []); // Пусто — выполнить один раз
  
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;
  
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Передача данных в fetch (POST с JSON)

const newUser = { name: "Jane", email: "jane@example.com" };

fetch("https://api.example.com/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json", // Важно!
  },
  body: JSON.stringify(newUser) // Преобразуем объект в JSON строку
})
  .then(response => response.json())
  .then(data => console.log("Ответ:", data));

Обработка неправильного JSON

fetch(url)
  .then(response => response.json())
  .catch(error => {
    // Это может быть и сетевая ошибка, и ошибка парсинга JSON
    console.error("Ошибка:", error);
  });

Если сервер вернёт невалидный JSON:

// Сервер вернул: "Not a JSON"
fetch(url)
  .then(response => response.json())
  .catch(error => {
    console.error(error); // SyntaxError: Unexpected token N in JSON at position 0
  });

Проверка Content-Type

fetch(url)
  .then(response => {
    // Проверяем, что это действительно JSON
    const contentType = response.headers.get("content-type");
    if (!contentType || !contentType.includes("application/json")) {
      throw new TypeError("Ответ не JSON");
    }
    return response.json();
  })
  .then(data => console.log(data));

Решение проблемы CORS при fetch

// Если API требует credentials (cookies)
fetch("https://api.example.com/users", {
  credentials: "include" // Отправить cookies
})
  .then(response => response.json())
  .then(data => console.log(data));

Абортирование fetch запроса

const controller = new AbortController();

fetch(url, { signal: controller.signal })
  .then(response => response.json())
  .catch(error => {
    if (error.name === "AbortError") {
      console.log("Запрос отменён");
    }
  });

// Отменить запрос
controller.abort();

Таймаут для fetch

async function fetchWithTimeout(url, timeout = 5000) {
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout);
  
  try {
    const response = await fetch(url, { signal: controller.signal });
    clearTimeout(id);
    return await response.json();
  } catch (error) {
    clearTimeout(id);
    if (error.name === "AbortError") {
      throw new Error("Таймаут запроса");
    }
    throw error;
  }
}

// Использование
fetchWithTimeout("https://api.example.com/users", 3000)
  .then(data => console.log(data))
  .catch(error => console.error(error));

Краткая схема

fetch(url)
  |
  v
  Promise<Response> (разрешится, когда приходит заголовок)
  |
  v
  response.json() -> Promise<any> (парсит тело как JSON)
  |
  v
  .then(data => {...}) -> data это уже объект JavaScript

Заключение

Чтобы получить JSON из fetch:

  1. Вызовите fetch(url)
  2. Дождитесь Response объекта
  3. Вызовите response.json() для парсинга
  4. Дождитесь распарсенных данных
  5. Используйте данные в .then() или await

Главное помнить:

  • response.json() это асинхронная операция (возвращает Promise)
  • Метод парсинга можно вызвать только один раз
  • Всегда проверяйте response.ok перед парсингом
  • Ошибки парсинга будут в .catch() блоке
Как получить JSON из fetch запроса? | PrepBro