Cors: что это такое и как исправить распространённые ошибки настройки

Понимание CORS: почему браузер блокирует запросы

Что такое CORS и зачем он нужен

CORS (Cross-Origin Resource Sharing) — это механизм безопасности, реализованный в современных браузерах, который ограничивает выполнение HTTP-запросов к ресурсам на другом домене, если они не разрешены сервером. Проще говоря, если ваш фронтенд размещён на `example.com`, а вы пытаетесь сделать запрос к API на `api.example.org`, браузер по умолчанию заблокирует его, считая кросс-доменным. CORS — не ошибка, а защита от возможных XSS-атак, когда вредоносный скрипт получает доступ к данным другого сайта.

Без корректной настройки CORS сервер вернёт заголовок, запрещающий доступ, или вовсе не отправит нужные заголовки, и тогда браузер выдаст типичную ошибку: `Access to fetch at 'https://api.example.org/data' from origin 'https://example.com' has been blocked by CORS policy`.

Как работает механизм CORS на техническом уровне

Когда браузер отправляет кросс-доменные запросы, он делает это в два этапа. В случае «простых» запросов (например, `GET` без нестандартных заголовков) отправляется основной запрос сразу. Однако если в запросе есть нестандартные заголовки (`Authorization`, `Content-Type: application/json` и др.), или используется метод `PUT`, `DELETE`, то сначала отправляется так называемый preflight-запрос методом `OPTIONS`.

Этот предварительный запрос проверяет, позволяет ли сервер выполнение основного запроса. Если сервер не отвечает с нужными HTTP-заголовками, такими как `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, браузер блокирует запрос.

Пример preflight-запроса:

```
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
```

И ожидаемый ответ от сервера:

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type
```

Типичные причины CORS-ошибок и как их исправить

Наиболее распространённые ошибки и их диагностика

Разработчики часто сталкиваются с ошибками CORS при работе с REST API, особенно на стадии локальной разработки. Одним из частых случаев является попытка выполнить запрос с фронтенда к API, размещённому на другом домене или порту. Браузер в этом случае выдает ошибку вида:

> Access to XMLHttpRequest at 'https://api.example.org/data' from origin 'http://localhost:3000' has been blocked by CORS policy.

Чтобы понять, как исправить ошибки CORS, необходимо:

1. Проверить, отправляется ли preflight-запрос.
2. Проанализировать ответ сервера: присутствуют ли нужные заголовки.
3. Убедиться, что сервер действительно поддерживает указанный origin.

Подходы к решению: серверная настройка

Что такое CORS и как исправить ошибки с ним связанные - иллюстрация

Наиболее корректный способ решения проблемы CORS — настройка соответствующих заголовков на сервере. Ниже приведены способы настройки для популярных технологий:

1. Node.js (Express):

```javascript
const cors = require('cors');
app.use(cors({ origin: 'http://localhost:3000' }));
```

2. Python (Flask):

```python
from flask_cors import CORS
CORS(app, origins="http://localhost:3000")
```

3. Nginx (проксирование):

```
location /api/ {
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
}
```

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

Альтернативные подходы: проксирование и заглушки

Иногда настройка CORS невозможна, особенно если вы работаете с внешним API, не поддерживающим нужные заголовки. В этом случае есть обходные пути:

1. Настройка прокси-сервера. Например, в React можно настроить `proxy` в `package.json`:

```json
"proxy": "https://api.example.org"
```

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

2. Использование серверной прослойки. Вы можете создать промежуточный сервер (middleware), который будет отправлять запросы к API от своего имени, а фронтенд будет обращаться только к вашему серверу.

3. CORS-заглушки и расширения. На этапе разработки можно использовать браузерные расширения (например, Allow CORS: Access-Control-Allow-Origin), но это решение категорически не подходит для продакшена.

Сравнение подходов: плюсы и минусы

1. Настройка CORS на сервере
- ✅ Безопасно, прозрачно
- ✅ Поддерживается всеми браузерами
- ❌ Требует доступа к серверу
- ❌ Нужно следить за безопасностью (не использовать `*` в `Access-Control-Allow-Origin`)

2. Проксирование через фронтенд
- ✅ Быстрый старт
- ✅ Не требует изменения API
- ❌ Может ломаться при сложных конфигурациях
- ❌ Не решает проблему во всех случаях (preflight всё равно может сработать)

3. Серверный middleware
- ✅ Гибко и контролируемо
- ✅ Полный контроль над запросами
- ❌ Увеличивает сложность архитектуры
- ❌ Может повлиять на производительность

Рекомендации для начинающих разработчиков

Что такое CORS и как исправить ошибки с ним связанные - иллюстрация

Если вы только начинаете работать с веб-разработкой и не понимаете, почему браузер блокирует ваши запросы — изучите, что такое CORS для начинающих. Начните с анализа заголовков запроса и ответа в DevTools (вкладка Network). Обратите внимание на наличие `Access-Control-Allow-Origin` и значение заголовка `Origin`.

Вот пошаговая инструкция, как исправить ошибки CORS:

1. Определите, к какому домену направлен запрос и отличается ли он от origin страницы.
2. Убедитесь, что сервер возвращает нужные заголовки CORS.
3. При необходимости — настройте прокси или middleware.
4. Не используйте `Access-Control-Allow-Origin: *` вместе с `credentials: true` — это вызовет ошибку.
5. Тестируйте запросы через curl или Postman, чтобы исключить ошибки, не связанные с CORS.

Заключение

Ошибки CORS — это не баг, а защита браузера. Их появление означает, что ваш клиент пытается получить доступ к ресурсу, который не разрешает такие запросы. Настройка CORS — важный этап в разработке API и фронтенда, особенно при работе в распределённых системах. Понимание механизма и правильный выбор стратегии — будь то настройка заголовков, проксирование или middleware — помогут вам избежать проблем и обеспечить безопасное взаимодействие между клиентом и сервером.

Прокрутить вверх