Как происходит проверка CORS в браузере?

«Как происходит проверка CORS в браузере?» — вопрос из категории Сети, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Последовательность проверки:

  1. Определение "простого" (simple) запроса: Браузер сразу отправляет основной запрос (без предварительной проверки), если он удовлетворяет всем критериям:

    • Методы: GET, POST, HEAD.
    • Заголовки: Только стандартные (Accept, Accept-Language, Content-Language, Content-Type с значениями application/x-www-form-urlencoded, multipart/form-data, text/plain).
  2. Предварительный запрос (Preflight Request) для "непростых" запросов: Если запрос не является "простым" (например, использует кастомный заголовок X-API-Key или метод PUT), браузер автоматически отправляет предварительный запрос методом OPTIONS на тот же URL.

    OPTIONS /api/data HTTP/1.1
    Origin: https://myfrontend.com
    Access-Control-Request-Method: PUT
    Access-Control-Request-Headers: X-API-Key, Content-Type
  3. Ответ сервера на Preflight: Сервер должен ответить с заголовками, разрешающими запрос:

    HTTP/1.1 204 No Content
    Access-Control-Allow-Origin: https://myfrontend.com
    Access-Control-Allow-Methods: GET, POST, PUT
    Access-Control-Allow-Headers: X-API-Key, Content-Type
    Access-Control-Max-Age: 86400 // Кэшировать ответ на 24 часа
  4. Основной запрос: Только если предварительный ответ удовлетворителен, браузер отправляет основной запрос. В ответе на основной запрос также должен присутствовать заголовок Access-Control-Allow-Origin.

Настройка в ASP.NET Core:

// В Program.cs
app.UseCors(builder => builder
    .WithOrigins("https://trusted-domain.com") // Конкретный origin
    .AllowAnyMethod()                          // Или .AllowMethods("GET", "POST")
    .AllowAnyHeader()                          // Или .WithHeaders("X-API-Key")
    .AllowCredentials());                      // Разрешить куки/авторизацию
// Важно: при использовании AllowCredentials() нельзя использовать WithOrigins("*").

Важно: CORS — это защита браузера. Инструменты вроде Postman или curl отправляют запросы напрямую и не выполняют проверки CORS.