Волга
Главная
Agent Skill
API Docs
GitHub
  • English
  • Русский
Главная
Agent Skill
API Docs
GitHub
  • English
  • Русский
  • Главная
  • Старт

    • Быстрый старт
    • Обработчики
    • Параметры маршрута
    • Параметры запроса
    • Группировка маршрутов
  • Запросы и ответы

    • Заголовки (Headers)
    • Работа с JSON
    • Работа с Form Data
    • Работа с файлами
    • Multipart-ответы
    • Сырое тело запроса
    • Cookies
    • Валидация запросов
  • Middleware и инфраструктура

    • Основы Middleware
    • Пользовательские Middleware
    • Параметризованные Middleware
    • Сжатие ответов
    • Распаковка запросов
    • CORS (Cross-Origin Resource Sharing)
    • Статические файлы
    • Rate Limiting
    • Файлы конфигурации
    • OpenAPI
  • Безопасность и доступ

    • Аутентификация и авторизация
    • OAuth 2.1 и OpenID Connect
    • OAuth 2.1 Клиент
    • Гранты «сервис-сервис»
    • DPoP — токены, привязанные к отправителю
  • Надежность и наблюдаемость

    • Центральный обработчик ошибок
    • Логгирование и Трассировка
    • Отмена запросов
    • Плавное завершение работы
  • Протоколы и realtime

    • Версии и методы HTTP
    • HTTPS
    • WebSockets
    • Server-Sent Events (SSE)
  • Продвинутые паттерны

    • Внедрение Зависимостей
    • Пользовательская обработка методов HEAD, OPTIONS и TRACE
  • Agent Skill

CORS (Cross-Origin Resource Sharing)

Волга поддерживает легко настраиваемый middleware для CORS.

Он входит в состав набора функций full. Однако, если вы его не используете, вы можете включить функцию middleware в Cargo.toml, чтобы добавить поддержку CORS:

[dependencies]
volga = { version = "...", features = ["middleware"] }

Базовая настройка

Следующий пример демонстрирует максимально разрешительную конфигурацию CORS:

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {   
    let mut app = App::new()
        .with_cors(|cors| cors
            .with_any_origin()
            .with_any_header()
            .with_any_method());

    // Включение CORS middleware
    app.use_cors();

    app.map_post("/", || async {});

    app.run().await
}

По умолчанию CORS отключен. Чтобы избежать паники во время выполнения, необходимо вызвать метод with_cors() до use_cors().

Если требуется более строгая конфигурация, можно указать конкретные разрешённые источники, заголовки и методы:

use volga::{App, http::Method};

#[tokio::main]
async fn main() -> std::io::Result<()> {   
    let mut app = App::new()
        .with_cors(|cors| cors
            .with_origins(["http://example.com", "http://example.net"])
            .with_headers(["Cache-Control", "Content-Language"])
            .with_methods([Method::GET, Method::POST]));

    // Включение CORS middleware
    app.use_cors();

    app.map_post("/", || async {});

    app.run().await
}

Примечание

Если вам нужно включить передачу учётных данных с помощью with_credentials(), учтите, что нельзя использовать эту настройку совместно с wildcard-значениями для источников, заголовков или методов по соображениям безопасности. Эти ограничения проверяются в use_cors(), и в случае некорректной конфигурации произойдёт паника. Метод не принимает аргументов — для явного отключения используйте without_credentials(). Аналогично, заголовок Vary управляется через with_vary_header() / without_vary_header().

Политики CORS и область действия

Волга разделяет конфигурацию CORS и место её применения:

  • with_cors() определяет одну или несколько политик CORS.
  • use_cors() включает CORS middleware (обязательно).
  • CORS применяется на основе:
  • Политики по умолчанию (применяется ко всем маршрутам, если не переопределена) или
  • Именованной политики (применяется только там, где это явно указано).

Именованная политика для группы маршрутов

Если вы настроите только именованную политику, маршруты не получат CORS, если вы явно не прикрепите эту политику с помощью cors_with(...).

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_cors(|cors| cors
        .with_name("policy")
        .with_origins(["https://example.com"])
        .with_any_header()
        .with_any_method());

    // Включить middleware (обязательно)
    app.use_cors();

    app.group("/api", |api| {
        // Применить CORS только для `/api/*`
        api.cors_with("policy");

        api.map_get("/users", || async {});
        api.map_post("/posts", || async {});
    });

    // Здесь CORS не применяется (именнованная политика не применяется)
    app.map_get("/internal", || async {});

    app.run().await
}

Именованная политика для отдельного маршрута

Вы можете прикрепить политику к одному маршруту:

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_cors(|cors| cors
        .with_name("permissive")
        .with_any_origin()
        .with_any_method()
        .with_any_header());

    app.use_cors();

    app.map_get("/public", || async {})
        .cors_with("permissive");

    app.map_get("/private", || async {})
        .disable_cors();

    app.run().await
}

Примечание

При использовании только именованных политик маршруты без явно прикрепленной политики не будут отправлять заголовки CORS.

Переопределение и отключение

CORS можно явно отключить для маршрута (или группы) с помощью disable_cors(). Это особенно полезно, когда у вас есть политика по умолчанию, включенная глобально, но вам нужно отключить ее для определенных конечных точек.

CORS для несовпавших запросов

Ответы 404 и 405 несут те же заголовки CORS, которые настроенная политика проставила бы на 200: глобальный middleware выполняется и для запросов, не совпавших ни с одним маршрутом, поэтому браузер получает осмысленную ошибку CORS вместо непрозрачной.

На preflight по-прежнему отвечают 204 только для существующего маршрута — ответить так на путь или метод, которые роутер не нашёл, значило бы объявить эндпоинт, которого нет. Такие запросы проваливаются в 404 / 405 и забирают заголовки на выходе. Middleware CORS различает эти случаи через matched_route().

Статические файлы

Политика CORS группы маршрутов до раздаваемых этой группой файлов не доходит. Политика выбирается по сработавшему маршруту, а статический файл раздаётся без маршрута, поэтому к файлам применяется политика приложения — заданная через with_cors(). По той же причине preflight, нацеленный на путь файла, обрабатывается как запрос к несуществующему пути: 404 с заголовками политики, а не 204. Кросс-доменные GET к статике его всё равно никогда не отправляют.

Полный пример доступен здесь.

Последнее обновление: 14.09.2026, 06:45
Prev
Распаковка запросов
Next
Статические файлы