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

Что такое CORS и как с ним работать?

1.3 Junior🔥 251 комментариев
#Браузер и сетевые технологии

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

🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)

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

Что такое CORS и как с ним работать

CORS (Cross-Origin Resource Sharing) это механизм, который позволяет веб-приложениям, работающим на одном домене, получать доступ к ресурсам на другом домене. Это был решен принципиальный вопрос безопасности браузеров.

Что такое Same-Origin Policy

Для защиты пользователей браузеры реализуют Same-Origin Policy (SOP) - политика, которая запрещает скриптам с одного сайта получать доступ к данным с другого сайта:

// Исходный сайт: https://example.com
// Браузер ДА разрешит:
fetch('https://example.com/api/data'); // Нет cross-origin

// Браузер НЕТ запретит:
fetch('https://api.other.com/data'); // Cross-origin!

Что такое CORS

CORS позволяет серверу явно указать браузеру: 'Ты можешь получить доступ к моим ресурсам'. Это делается через HTTP заголовки.

Как работает CORS на примере

1. Простой запрос (Simple Request)

Для простых GET/POST запросов браузер сразу отправляет запрос, но проверяет ответ:

// Frontend: https://example.com
fetch('https://api.other.com/data')
  .then(response => response.json())
  .catch(error => console.error('CORS Error:', error));

// HTTP запрос:
// GET /data HTTP/1.1
// Origin: https://example.com

// Ответ сервера:
// Access-Control-Allow-Origin: https://example.com
// Access-Control-Allow-Methods: GET, POST
// Access-Control-Allow-Headers: Content-Type

2. Preflight запрос (Preflight Request)

Для сложных запросов (PUT, DELETE, с custom headers) браузер сначала отправляет OPTIONS запрос:

// Frontend запрашивает PUT с Authorization:
fetch('https://api.other.com/user/123', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify({ name: 'John' })
});

// Браузер автоматически отправляет PREFLIGHT:
// OPTIONS /user/123 HTTP/1.1
// Origin: https://example.com
// Access-Control-Request-Method: PUT
// Access-Control-Request-Headers: authorization

// Если сервер разрешает, ответит:
// HTTP/1.1 204 No Content
// Access-Control-Allow-Origin: https://example.com
// Access-Control-Allow-Methods: PUT, DELETE
// Access-Control-Allow-Headers: authorization, content-type

// ТОЛЬКОhttps://api.other.com тогда браузер отправит актуальный PUT запрос

CORS заголовки на сервере

// Node.js + Express пример
app.use((req, res, next) => {
  // Позволить конкретному origin
  res.header('Access-Control-Allow-Origin', 'https://example.com');
  
  // Или позволить всем (НЕ рекомендуется для production)
  res.header('Access-Control-Allow-Origin', '*');
  
  // Методы, которые разрешены
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  
  // Headers, которые разрешены
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  
  // Позволить отправку credentials (cookies, auth headers)
  res.header('Access-Control-Allow-Credentials', 'true');
  
  // Как долго кешировать preflight ответ (в секундах)
  res.header('Access-Control-Max-Age', '3600');
  
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  
  next();
});

Как работать с CORS на frontend

1. Базовый fetch с CORS

fetch('https://api.other.com/data')
  .then(response => response.json())
  .catch(error => console.error('Ошибка:', error));

2. Отправка credentials (cookies)

fetch('https://api.other.com/user', {
  method: 'GET',
  credentials: 'include' // Отправить cookies
})
.then(response => response.json());

3. Обработка ошибок CORS

fetch('https://api.other.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .catch(error => {
    if (error instanceof TypeError) {
      console.error('CORS Error: Запрос был заблокирован браузером');
    } else {
      console.error('Ошибка:', error.message);
    }
  });

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

Проблема 1: 'Access to XMLHttpRequest has been blocked'

Решение: Настроить CORS на сервере или использовать proxy

// В development используй proxy (next.js rewrites):
// next.config.js
module.exports = {
  rewrites: async () => ({
    beforeFiles: [
      {
        source: '/api/:path*',
        destination: 'https://api.other.com/:path*'
      }
    ]
  })
};

// Тогда запрос на /api/data будет проксирован на https://api.other.com/data

Проблема 2: Preflight запрос медленит приложение

Решение: Кешировать preflight с Access-Control-Max-Age

CORS и Credentials

// Отправить request с credentials (cookies, Basic auth)
fetch('https://api.other.com/user', {
  method: 'POST',
  credentials: 'include', // ВАЖНО!
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ data: 'test' })
});

// Сервер ДОЛЖЕН ответить:
// Access-Control-Allow-Credentials: true
// Access-Control-Allow-Origin: https://example.com (КОНКРЕТНЫЙ, не *)

Итого

CORS это критичный механизм современного веб:

  • Позволяет безопасно делиться ресурсами между сайтами
  • Требует явного разрешения от сервера
  • Использует HTTP заголовки для контроля доступа
  • В production всегда указывай конкретные origins, не дикие *
Что такое CORS и как с ним работать? | PrepBro