# CORS (Cross-Origin Resource Sharing) { #cors-cross-origin-resource-sharing }

<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Понятие CORS или "Cross-Origin Resource Sharing"</a> относится к ситуациям, при которых запущенный в браузере фронтенд содержит JavaScript-код, который взаимодействует с бэкендом, находящимся на другом "источнике" ("origin").

## Источник { #origin }

Источник — это совокупность протокола (`http`, `https`), домена (`myapp.com`, `localhost`, `localhost.tiangolo.com`) и порта (`80`, `443`, `8080`).

Поэтому это три разных источника:

* `http://localhost`
* `https://localhost`
* `http://localhost:8080`

Даже если они все расположены в `localhost`, они используют разные протоколы или порты, а значит, являются разными источниками.

## Шаги { #steps }

Допустим, у вас есть фронтенд, запущенный в браузере по адресу `http://localhost:8080`, и его JavaScript-код пытается взаимодействовать с бэкендом, запущенным по адресу `http://localhost` (поскольку мы не указали порт, браузер по умолчанию будет использовать порт `80`).

Затем браузер отправит на бэкенд на `:80` HTTP-запрос `OPTIONS`, и если бэкенд вернёт соответствующие HTTP-заголовки, авторизующие взаимодействие с другим источником (`http://localhost:8080`), то браузер на `:8080` разрешит JavaScript на фронтенде отправить свой запрос на бэкенд на `:80`.

Чтобы это работало, у бэкенда на `:80` должен быть список "разрешённых источников" ("allowed origins").

В таком случае этот список должен содержать `http://localhost:8080`, чтобы фронтенд на `:8080` работал корректно.

## Подстановочный символ "*" { #wildcards }

В качестве списка источников можно указать подстановочный символ `"*"` ("wildcard"), чтобы разрешить любые источники.

Но тогда будут разрешены только некоторые виды взаимодействия, и всё, что связано с учётными данными, будет исключено: куки, HTTP-заголовки Authorization, как при использовании Bearer-токенов, и т.п.

Поэтому, чтобы всё работало корректно, лучше явно указывать список разрешённых источников.

## Использование `CORSMiddleware` { #use-corsmiddleware }

Вы можете настроить это в вашем **FastAPI**-приложении, используя `CORSMiddleware`.

* Импортируйте `CORSMiddleware`.
* Создайте список разрешённых источников (в виде строк).
* Добавьте его как "middleware" (промежуточный слой) к вашему **FastAPI**-приложению.

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

* Учётных данных (HTTP-заголовки Authorization, куки и т.п.).
* Отдельных HTTP-методов (`POST`, `PUT`) или всех вместе, используя `"*"`.
* Отдельных HTTP-заголовков или всех вместе, используя `"*"`.

{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}

`CORSMiddleware` использует "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте.

Поддерживаются следующие аргументы:

* `allow_origins` - Список источников, на которые разрешено выполнять кросс-доменные запросы. Например, `['https://example.org', 'https://www.example.org']`. Можно использовать `['*']`, чтобы разрешить любые источники.
* `allow_origin_regex` - Регулярное выражение для определения источников, на которые разрешено выполнять кросс-доменные запросы. Например, `'https://.*\.example\.org'`.
* `allow_methods` - Список HTTP-методов, которые разрешены для кросс-доменных запросов. По умолчанию `['GET']`. Можно использовать `['*']`, чтобы разрешить все стандартные методы.
* `allow_headers` - Список HTTP-заголовков запроса, которые должны поддерживаться при кросс-доменных запросах. По умолчанию `[]`. Можно использовать `['*']`, чтобы разрешить все заголовки. Заголовки `Accept`, `Accept-Language`, `Content-Language` и `Content-Type` всегда разрешены для <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">простых CORS-запросов</a>.
* `allow_credentials` - Указывает, что куки разрешены в кросс-доменных запросах. По умолчанию `False`.

    Ни один из параметров `allow_origins`, `allow_methods` и `allow_headers` не может быть установлен в `['*']`, если `allow_credentials` имеет значение `True`. Все они должны быть <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards" class="external-link" rel="noopener" target="_blank">указаны явно</a>.

* `expose_headers` - Указывает любые заголовки ответа, которые должны быть доступны браузеру. По умолчанию `[]`.
* `max_age` - Устанавливает максимальное время в секундах, в течение которого браузер кэширует CORS-ответы. По умолчанию `600`.

`CORSMiddleware` отвечает на два типа HTTP-запросов...

### CORS-запросы с предварительной проверкой { #cors-preflight-requests }

Это любые `OPTIONS`-запросы с заголовками `Origin` и `Access-Control-Request-Method`.

В этом случае middleware перехватит входящий запрос и отправит соответствующие CORS-заголовки в ответе, а также ответ `200` или `400` в информационных целях.

### Простые запросы { #simple-requests }

Любые запросы с заголовком `Origin`. В этом случае middleware передаст запрос дальше как обычно, но добавит соответствующие CORS-заголовки к ответу.

## Больше информации { #more-info }

Для получения более подробной информации о <abbr title="Cross-Origin Resource Sharing – совместное использование ресурсов между источниками">CORS</abbr> обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">документации CORS от Mozilla</a>.

/// note | Технические детали

Вы также можете использовать `from starlette.middleware.cors import CORSMiddleware`.

**FastAPI** предоставляет несколько middleware в `fastapi.middleware` только для вашего удобства как разработчика. Но большинство доступных middleware взяты напрямую из Starlette.

///
