Перейти к содержимому
Skip to content
← Все статьи

CORS: руководство по Cross-Origin Resource Sharing

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

Политика одного источника (Same-Origin Policy)

Политика одного источника — один из фундаментальных механизмов безопасности веба. Два URL имеют одинаковый источник, если совпадают протокол, домен и порт:

URL AURL BОдин источник?Причина
SSL/TLS проверку://example.com/page1https://example.com/page2ДаОдинаковые протокол, домен, порт
https://example.comhttp://example.comНетРазный протокол
https://example.comhttps://API документацию.example.comНетДругой субдомен
https://example.comhttps://example.com:8080НетДругой порт
https://example.comhttps://other.comНетДругой домен

Без политики одного источника любой сайт мог бы читать данные из вашего банковского приложения, почты или соцсетей через JavaScript — при условии, что вы авторизованы.

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

CORS работает через проверку HTTP-заголовков. При кросс-доменном запросе браузер включает заголовок Origin. Сервер отвечает заголовками Access-Control-*, указывая, разрешён ли запрос:

# Браузер отправляет:
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com

# Сервер отвечает:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json

{"data": "response"}

Если сервер не включает соответствующие CORS-заголовки, браузер блокирует ответ и логирует ошибку CORS в консоли.

Простые запросы и preflight-запросы

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

Простые запросы

Запрос считается «простым», если выполнены все условия:

Простые запросы отправляются напрямую. Браузер проверяет заголовки ответа постфактум.

Preflight-запросы

Любой запрос, не являющийся «простым», запускает preflight — автоматический OPTIONS-запрос перед фактическим запросом:

# Шаг 1: Браузер отправляет preflight
OPTIONS /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization

# Шаг 2: Сервер отвечает на preflight
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

# Шаг 3: Браузер отправляет фактический запрос
PUT /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGci...

{"key": "value"}

Справочник по заголовкам CORS

ЗаголовокНаправлениеНазначение
OriginЗапросСообщает серверу, откуда пришёл запрос
Access-Control-Allow-OriginОтветКакие источники могут обращаться к ресурсу
Access-Control-Allow-MethodsОтветРазрешённые HTTP-методы для preflight
Access-Control-Allow-HeadersОтветРазрешённые заголовки запроса для preflight
Access-Control-Allow-CredentialsОтветРазрешены ли cookies/заголовки авторизации
Access-Control-Expose-HeadersОтветЗаголовки ответа, доступные через JS
Access-Control-Max-AgeОтветВремя кэширования результата preflight (секунды)
Access-Control-Request-MethodЗапросМетод фактического запроса (preflight)
Access-Control-Request-HeadersЗапросЗаголовки фактического запроса (preflight)

Типичные конфигурации CORS

Разрешить конкретный источник

# Nginx
location /api/ {
    add_header Access-Control-Allow-Origin "https://app.example.com" always;
    add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
    add_header Access-Control-Max-Age 86400 always;

    if ($request_method = OPTIONS) {
        return 204;
    }

    proxy_pass http://backend;
}

Разрешить несколько источников (динамически)

# Nginx — проверка Origin по списку
map $http_origin $cors_origin {
    default "";
    "https://app.example.com" $http_origin;
    "https://admin.example.com" $http_origin;
    "https://staging.example.com" $http_origin;
}

server {
    location /api/ {
        add_header Access-Control-Allow-Origin $cors_origin always;
        add_header Vary Origin always;
    }
}

Обработчик CORS в PHP

$allowedOrigins = [
    'https://app.example.com',
    'https://admin.example.com',
];

$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowedOrigins, true)) {
    header("Access-Control-Allow-Origin: $origin");
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');
    header('Vary: Origin');
}

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

CORS с учётными данными

Когда запросы включают cookies или заголовки авторизации, действуют дополнительные правила:

// Клиентский JavaScript
fetch('https://api.example.com/data', {
    method: 'GET',
    credentials: 'include',  // Отправлять cookies кросс-доменно
    headers: {
        'Authorization': 'Bearer token123'
    }
});

Частые ошибки CORS и решения

ОшибкаПричинаРешение
No 'Access-Control-Allow-Origin' headerСервер не отправляет CORS-заголовкиДобавить CORS-заголовки в ответ сервера
Origin not allowedСервер разрешает другие источникиДобавить ваш источник в список разрешённых
Preflight response not successfulOPTIONS-запрос возвращает ошибкуОбработать метод OPTIONS, вернуть 204
Credentials с Allow-Origin: *Wildcard запрещён с credentialsУказать конкретный источник вместо *
Request header not allowedЗаголовок не в Allow-HeadersДобавить заголовок в Access-Control-Allow-Headers

Лучшие практики безопасности

CORS и мониторинг

Для веб-мониторинг сайтов CORS влияет на взаимодействие инструментов с API:

Итоги

CORS — механизм безопасности браузера, контролирующий кросс-доменные HTTP-запросы. Он использует HTTP-заголовки для определения, может ли веб-страница с одного источника обращаться к ресурсам с другого. Простые запросы отправляются напрямую; сложные запросы запускают preflight OPTIONS-проверку. Правильная настройка CORS требует указания разрешённых источников, методов и заголовков — с особой осторожностью при запросах с учётными данными. Понимание CORS необходимо всем, кто создаёт или использует веб-API, так как неправильная конфигурация ведёт либо к уязвимостям, либо к нерабочему функционалу.

Проверьте ваш сайт прямо сейчас

Проверить →
Другие статьи: Безопасность
Безопасность
Безопасность API: лучшие практики защиты
11.03.2026 · 14 просм.
Безопасность
WAF: что это и как защищает сайт
14.03.2026 · 12 просм.
Безопасность
Безопасность cookies: HttpOnly, Secure, SameSite
14.03.2026 · 11 просм.
Безопасность
Открытые порты сервера: как проверить и почему это важно для безопасности
13.03.2026 · 10 просм.