\n```\n\n**2. Proxy на бэкенде**\n\n```\nФронтенд → Свой бэкенд (/api/users) → Внешний API\nЭто обходит CORS, но добавляет latency\n```\n\n**3. WebSocket**\n\n```javascript\n// WebSocket не подвергается CORS ограничениям\nconst ws = new WebSocket('wss://api.example.com/ws');\n```\n\n### Вывод\n\nCORS — это критический механизм безопасности:\n\n- **Same-Origin Policy** — ограничивает кросс-доменные запросы\n- **CORS заголовки** — сервер разрешает конкретные источники\n- **Preflight запрос** — для сложных запросов браузер проверяет разрешение\n- **Правильная конфигурация** — критична для безопасности и функциональности\n\nЛюбой бэкенд-разработчик ДОЛЖЕН понимать и правильно конфигурировать CORS для защиты своего API.","dateCreated":"2026-03-28T21:48:08.721349","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Для чего используется CORS?

1.8 Middle🔥 191 комментариев
#API и сетевые протоколы#Безопасность

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

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

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

Использование CORS (Cross-Origin Resource Sharing)

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

Проблема: Same-Origin Policy (SOP)

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

"Скрипт может получать данные только с того же источника (домена, протокола и порта)"

Основной источник: https://example.com:443

✅ Разрешено:
  - https://example.com/api        (тот же домен)
  - https://example.com:443/data   (тот же протокол и порт)
  
❌ Заблокировано:
  - http://example.com/api         (другой протокол)
  - https://api.example.com        (субдомен считается другим источником)
  - https://example2.com           (другой домен)
  - https://example.com:8080       (другой порт)

Пример блокировки

// Загрузить страницу с https://myapp.com
// Попробать запрос с фронта
fetch('https://api.example.com/users')
  .then(r => r.json())
  .catch(e => console.log(e));

// Ошибка в консоли:
// Access to XMLHttpRequest at 'https://api.example.com/users' 
// from origin 'https://myapp.com' has been blocked by CORS policy: 
// No 'Access-Control-Allow-Origin' header is present on the requested resource.

Зачем нужен CORS

1. Безопасность

CORS защищает от атак:

<!-- Вредоносный сайт hack.com -->
<img src="https://bank.com/api/transfer?to=attacker&amount=1000">

<!-- Без CORS: браузер выполнит запрос от имени пользователя -->
<!-- С CORS: браузер заблокирует запрос, если нет правильного заголовка -->

2. Контроль доступа

Сервер может разрешить доступ только конкретным клиентам:

Сервер API (api.example.com):
  - Может разрешить запросы с app.example.com
  - Может разрешить запросы с mobile.example.com
  - Но заблокировать с hack.com

3. Управление методами и заголовками

Сервер может разрешить только определённые HTTP методы и заголовки.

Как работает CORS

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

Для простых запросов (GET, POST, HEAD) с стандартными заголовками:

1. Браузер отправляет запрос с заголовком Origin
   GET /api/users
   Host: api.example.com
   Origin: https://myapp.com

2. Сервер проверяет Origin и отвечает
   HTTP/1.1 200 OK
   Access-Control-Allow-Origin: https://myapp.com
   Content-Type: application/json
   
   [{"id": 1, "name": "John"}]

3. Браузер получает ответ и позволяет скрипту его использовать

Preflight запрос (для сложных запросов):

Для сложных запросов (PUT, DELETE, PATCH) или кастомных заголовков браузер сначала отправляет OPTIONS запрос:

1. Браузер отправляет preflight (OPTIONS) запрос
   OPTIONS /api/users
   Host: api.example.com
   Origin: https://myapp.com
   Access-Control-Request-Method: PUT
   Access-Control-Request-Headers: content-type

2. Сервер отвечает, что это разрешено
   HTTP/1.1 200 OK
   Access-Control-Allow-Origin: https://myapp.com
   Access-Control-Allow-Methods: GET, POST, PUT, DELETE
   Access-Control-Allow-Headers: content-type
   Access-Control-Max-Age: 86400  (кэширование на 24 часа)

3. Браузер отправляет реальный запрос
   PUT /api/users/1
   ...
   
4. Сервер отвечает нормально

CORS заголовки

На стороне сервера (ответ):

// Express пример
import cors from 'cors';

app.use(cors({
  origin: 'https://myapp.com',           // Разрешённый источник
  methods: ['GET', 'POST', 'PUT'],       // Разрешённые методы
  allowedHeaders: ['Content-Type', 'Authorization'],  // Разрешённые заголовки
  credentials: true,                     // Разрешить cookies
  maxAge: 86400                          // Кэширование preflight на 24 часа
}));

// Или вручную
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', 'https://myapp.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.setHeader('Access-Control-Max-Age', '86400');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  
  if (req.method === 'OPTIONS') {
    res.sendStatus(200);
  } else {
    next();
  }
});

На стороне клиента (запрос):

// Fetch с credentials (cookies, auth headers)
fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify({ name: 'John' }),
  credentials: 'include'  // Отправить cookies вместе с запросом
})
.then(r => r.json())
.catch(e => console.log('CORS ошибка:', e));

CORS стратегии

1. Разрешить все (небезопасно)

app.use(cors());
// или
res.setHeader('Access-Control-Allow-Origin', '*');

2. Разрешить конкретные домены

const allowedOrigins = [
  'https://myapp.com',
  'https://app.myapp.com',
  'https://mobile.myapp.com'
];

app.use(cors({
  origin: (origin, callback) => {
    if (allowedOrigins.includes(origin) || !origin) {
      callback(null, true);
    } else {
      callback(new Error('CORS не разрешён'));
    }
  }
}));

3. Разрешить с паттернами

app.use(cors({
  origin: /myapp\.com$/  // Разрешить все поддомены *.myapp.com
}));

Сценарии использования

Сценарий 1: SPA (Single Page Application)

Фронтенд: https://app.example.com
Бэкенд: https://api.example.com

Без CORS: фронтенд не может делать запросы к бэкенду
С CORS: бэкенд разрешает запросы с app.example.com

Сценарий 2: Мобильное приложение

Мобильный клиент НЕ использует CORS (это только для браузера)
Мобильное приложение может напрямую подключиться к API

Поэтому мобильные приложения часто используют другую авторизацию:
- API ключи
- OAuth токены
- JWT токены

Сценарий 3: Server-to-Server

Если бэкенд вызывает другой бэкенд, CORS НЕ применяется
CORS применяется только когда браузер делает запрос

Server A → Server B: работает без CORS
Браузер → Server A: CORS проверяется

Проблемы и решения

Проблема: credentials не отправляются

// ❌ Неправильно
fetch('https://api.example.com/users');

// ✅ Правильно
fetch('https://api.example.com/users', {
  credentials: 'include'  // Отправить cookies
});

// На сервере тоже нужно разрешить
res.setHeader('Access-Control-Allow-Credentials', 'true');

Проблема: кастомные заголовки блокируются

// Клиент отправляет:
fetch('https://api.example.com/users', {
  headers: {
    'X-Custom-Header': 'value'
  }
});

// Сервер должен разрешить:
res.setHeader('Access-Control-Allow-Headers', 'X-Custom-Header, Content-Type');

Альтернативы CORS

1. JSONP (устаревший способ)

// Работал в старых браузерах, но не безопасный
<script src="https://api.example.com/users?callback=handleData"></script>

2. Proxy на бэкенде

Фронтенд → Свой бэкенд (/api/users) → Внешний API
Это обходит CORS, но добавляет latency

3. WebSocket

// WebSocket не подвергается CORS ограничениям
const ws = new WebSocket('wss://api.example.com/ws');

Вывод

CORS — это критический механизм безопасности:

  • Same-Origin Policy — ограничивает кросс-доменные запросы
  • CORS заголовки — сервер разрешает конкретные источники
  • Preflight запрос — для сложных запросов браузер проверяет разрешение
  • Правильная конфигурация — критична для безопасности и функциональности

Любой бэкенд-разработчик ДОЛЖЕН понимать и правильно конфигурировать CORS для защиты своего API.

Для чего используется CORS? | PrepBro