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

Как CORS понимает какой кросс-доменный запрос блокировать?

1.8 Middle🔥 171 комментариев
#JavaScript Core

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

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

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

Как CORS понимает какой кросс-доменный запрос блокировать?

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

Что такое Origin (источник)?

Основной параметр для CORS — это Origin, который состоит из трёх частей:

Protocol://Domain:Port
https://example.com:443
https://api.example.com:443

Два запроса имеют РАЗНЫЕ origins, если различаются протокол, домен ИЛИ порт:

https://example.com       <- Origin
https://api.example.com   <- ДРУГОЙ Origin (разный домен)
https://example.com:8000  <- ДРУГОЙ Origin (разный порт)
http://example.com        <- ДРУГОЙ Origin (разный протокол)

Как браузер блокирует кросс-доменные запросы?

1. Браузер отправляет Origin заголовок

Когда ваш JavaScript код на https://frontend.com делает запрос к https://api.com, браузер автоматически добавляет заголовок:

GET /users HTTP/1.1
Host: api.com
Origin: https://frontend.com  <- Браузер добавляет автоматически

2. Сервер отвечает с CORS заголовками

Сервер должен ответить с заголовком Access-Control-Allow-Origin:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://frontend.com  <- Указывает какой Origin разрешён
Content-Type: application/json

{"data": ...}

3. Браузер проверяет заголовки и принимает решение

// На frontend.com делаем запрос к api.com
fetch('https://api.com/users')
  .then(response => response.json())
  .catch(error => console.error('CORS Error:', error));

// Браузер проверяет:
// 1. Origin в ответе совпадает с текущим origin?
// 2. Если да - разрешить доступ к данным
// 3. Если нет или заголовок отсутствует - БЛОКИРОВАТЬ (выбросить ошибку)

Практический пример

Сценарий 1: Разрешённый запрос

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

Браузер отправляет:
GET /users
Origin: https://frontend.com

Бэкенд отвечает:
Access-Control-Allow-Origin: https://frontend.com  <- Совпадает!

Результат: РАЗРЕШЕНО

Сценарий 2: Запрещённый запрос

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

Браузер отправляет:
GET /users
Origin: https://evil.com

Бэкенд отвечает:
Access-Control-Allow-Origin: https://frontend.com  <- НЕ совпадает!

Результат: БЛОКИРОВАНО - CORS Error

Типы запросов и Preflight

Simple Requests (не требуют preflight):

// GET, POST, HEAD с определёнными заголовками
fetch('https://api.com/users');

Complex Requests (требуют preflight проверки):

// PUT, DELETE, PATCH, или специальные заголовки
fetch('https://api.com/users/123', {
  method: 'DELETE',  // Сложный метод
  headers: {
    'Authorization': 'Bearer token'  // Специальный заголовок
  }
});

// Браузер сначала отправляет OPTIONS запрос:
// OPTIONS /users/123
// Origin: https://frontend.com
// Access-Control-Request-Method: DELETE
// Access-Control-Request-Headers: authorization

// Сервер должен ответить:
// Access-Control-Allow-Origin: https://frontend.com
// Access-Control-Allow-Methods: GET, POST, DELETE
// Access-Control-Allow-Headers: Authorization

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

Запрос от браузера:

  • Origin — откуда идёт запрос
  • Access-Control-Request-Method — какой метод нужен (для preflight)
  • Access-Control-Request-Headers — какие заголовки нужны (для preflight)

Ответ от сервера:

  • Access-Control-Allow-Origin — какие origins разрешены
  • Access-Control-Allow-Methods — какие HTTP методы разрешены
  • Access-Control-Allow-Headers — какие заголовки разрешены
  • Access-Control-Max-Age — как долго кэшировать preflight
  • Access-Control-Allow-Credentials — разрешены ли cookies

Конфигурация на бэкенде (пример на Express.js)

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

// Разрешить один конкретный origin
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://frontend.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, PUT');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  next();
});

// Или использовать middleware
const cors = require('cors');
app.use(cors({
  origin: 'https://frontend.com',
  methods: ['GET', 'POST', 'DELETE', 'PUT'],
  credentials: true
}));

Частые ошибки

Ошибка 1: Указать wildcard для credentials

// НЕПРАВИЛЬНО - несовместимо
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

// ПРАВИЛЬНО
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Credentials: true

Ошибка 2: Забыть разрешить методы

// Если frontend отправляет DELETE запрос,
// нужно явно разрешить:
Access-Control-Allow-Methods: GET, POST, DELETE

Выводы

CORS блокирует кросс-доменные запросы на основе:

  1. Origin заголовка — браузер автоматически указывает источник
  2. Access-Control-Allow-Origin — сервер указывает разрешённые origins
  3. Совпадения — если они совпадают, запрос разрешен, нет — блокирован
  4. Preflight проверка — для сложных запросов браузер сначала проверяет возможность

Это механизм безопасности, который предотвращает злоумышленникам использовать ваши API от имени пользователя.

Как CORS понимает какой кросс-доменный запрос блокировать? | PrepBro