CORS в React и Axios: Полное руководство по исправлению ошибок безопасности браузера

CORS в React и Axios: Полное руководство по исправлению ошибок безопасности браузера

Вы разрабатываете крутое React-приложение, подключаетесь к API через axios, и вдруг — красная ошибка в консоли: «CORS policy blocked». Знакомо? Эта ошибка безопасности браузера ломает работу тысяч разработчиков ежедневно. Но не волнуйтесь — CORS не враг, а защитник. В этой статье мы глубоко разберем природу этой ошибки и покажем все рабочие способы ее решения: от быстрых хаков до правильных production-решений.

Что такое CORS и почему он вас блокирует?

CORS (Cross-Origin Resource Sharing) — это механизм безопасности браузера, который запрещает запросы с одного домена (origin) к ресурсам другого домена, если сервер явно не разрешил это. Когда ваш React-приложение на localhost:3000 пытается получить данные с api.example.com, браузер отправляет «preflight» запрос (OPTIONS), чтобы спросить: «Можно ли?». Если сервер отвечает без правильных заголовков — получаете ошибку.

Важно: CORS работает только в браузерах! Если вы делаете запрос с Node.js-сервера или через Postman — ошибки не будет. Это исключительно браузерная защита.

Способы исправления CORS ошибки в React + Axios

1. Настройка сервера (правильный способ)

Идеальное решение — добавить правильные заголовки на стороне сервера, которому вы отправляете запрос. Пример для Node.js/Express:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  next();
});

Для production можно использовать динамическое разрешение origins или whitelist доменов.

2. Прокси-сервер в development (create-react-app)

В файле package.json вашего React-приложения добавьте:

"proxy": "https://api.example.com"

Теперь все запросы к /api будут перенаправляться через dev-сервер React, избегая CORS. В axios просто указывайте относительный путь:

axios.get('/api/users')

Примечание: Прокси работает только в development-режиме (npm start). Для production нужен другой подход.

3. Собственный прокси-сервер (Production решение)

Создайте простой Node.js-сервер, который будет принимать запросы от вашего React-приложения и перенаправлять их к целевому API. Это полностью решает CORS проблему.

const express = require('express');
const axios = require('axios');
const app = express();

app.use('/api', async (req, res) => {
  try {
    const response = await axios({
      method: req.method,
      url: `https://target-api.com${req.url}`,
      data: req.body
    });
    res.json(response.data);
  } catch (error) {
    res.status(error.response?.status || 500).json({ error: error.message });
  }
});

4. Chrome расширения для development (временное решение)

Установите расширение типа «Allow CORS: Access-Control-Allow-Origin» — оно добавляет нужные заголовки ко всем ответам. Только для разработки! Никогда не просите пользователей устанавливать такие расширения.

5. JSONP (для старых API)

Если API поддерживает JSONP, можно использовать этот обходной путь. Но у метода есть серьезные ограничения безопасности и он работает только для GET-запросов.

6. Настройка axios с credentials

Если ваш запрос требует cookies или аутентификации, нужно правильно настроить axios:

axios.defaults.withCredentials = true;
// И на сервере добавить:
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // Нельзя использовать '*'

Чего НЕ делать: опасные антипаттерны

  • Не отключайте CORS в браузере через флаги типа --disable-web-security
  • Не используйте заголовок 'Access-Control-Allow-Origin: *' с credentials
  • Не просите пользователей отключать безопасность браузера
  • Не игнорируйте CORS в production — это уязвимость!

FAQ: Частые вопросы о CORS

Почему CORS ошибка возникает только в браузере?

CORS — это политика браузера. Серверные приложения (Node.js, Python) и инструменты типа Postman не имеют таких ограничений.

Как отличить CORS ошибку от других?

В консоли браузера будет сообщение содержащее «CORS policy», «Access-Control-Allow-Origin» или «preflight request».

Работает ли CORS с локальными файлами (file://)?

Нет, большинство браузеров блокируют запросы с file:// протокола из соображений безопасности.

Можно ли обойти CORS без доступа к серверу?

Только через прокси-сервер или если API поддерживает JSONP. В остальных случаях нужен доступ к серверным заголовкам.

Почему OPTIONS запрос отправляется дважды?

Preflight запрос (OPTIONS) отправляется для «непростых» запросов (с кастомными заголовками, Content-Type не text/plain и т.д.). Это нормальное поведение.

Итог: CORS — ваш друг, а не враг. Правильное решение — настройка сервера или создание прокси. Временные решения используйте только в development. Безопасность важнее удобства!