Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает CORS (Cross-Origin Resource Sharing)
Проблема
Браузер по умолчанию блокирует запросы с одного домена к другому (Same-Origin Policy). Это основная защита от атак. Но иногда нам нужно разрешить запросы между разными доменами контролируемым образом.
Что такое Origin?
Origin — это комбинация протокола, хоста и порта:
- https://example.com (origin)
- https://example.com:8443 (другой origin, разные порты)
- https://api.example.com (другой origin, разный хост)
- http://example.com (другой origin, разный протокол)
Как работает CORS
1. Simple Request (простой запрос)
Для простых GET, HEAD, POST запросов браузер напрямую отправляет запрос и ждет заголовка Access-Control-Allow-Origin:
Покупатель: Сервер:
Отправляет запрос
↓
GET /api/data
Origin: https://client.com
↓
Получает запрос
↓
Проверяет Origin
↓
Отправляет ответ с заголовком:
Access-Control-Allow-Origin: https://client.com
↓
Получает ответ
Браузер проверяет заголовок
Если Origin совпадает — разрешает доступ
Пример на Python (FastAPI):
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://client.com"], # Или ["*"] для всех
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/api/data")
async def get_data():
return {"data": "hello"}
2. Preflight Request (предварительный запрос)
Для сложных запросов (PUT, DELETE, с кастомными заголовками) браузер сначала отправляет OPTIONS запрос:
Браузер: Сервер:
Отправляет OPTIONS
↓
OPTIONS /api/data
Origin: https://client.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Authorization
↓
Сервер проверяет, разрешен ли DELETE
и заголовок Authorization
↓
Отправляет ответ:
Access-Control-Allow-Origin: https://client.com
Access-Control-Allow-Methods: DELETE, POST
Access-Control-Allow-Headers: Authorization
Access-Control-Max-Age: 86400
↓
Браузер получает ответ
Если методы и заголовки разрешены,
отправляет основной запрос DELETE
Пример:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://client.com"],
allow_credentials=True,
allow_methods=["GET", "POST", "DELETE", "PUT"], # Разрешённые методы
allow_headers=["Authorization", "Content-Type"], # Разрешённые заголовки
max_age=3600, # Кэшируем preflight на 1 час
)
@app.delete("/api/data/{item_id}")
async def delete_data(item_id: int):
return {"deleted": item_id}
Важные заголовки CORS
На сервере отправляет:
Access-Control-Allow-Origin— какие origin допускаютсяAccess-Control-Allow-Methods— какие HTTP методыAccess-Control-Allow-Headers— какие заголовки в запросеAccess-Control-Allow-Credentials— разрешить ли cookies/authAccess-Control-Max-Age— как долго кэшировать preflight
Браузер отправляет:
Origin— откуда идет запросAccess-Control-Request-Method— какой метод нужен (в preflight)Access-Control-Request-Headers— какие заголовки нужны (в preflight)
Частые ошибки
# ❌ Плохо — разрешаем всем
allow_origins=["*"]
allow_credentials=True # Будет ошибка!
# ✅ Хорошо — явно указываем origins
allow_origins=["https://client.com", "https://admin.com"]
allow_credentials=True
# ❌ Плохо — забыли про preflight
allow_methods=["GET"] # DELETE не разрешен
# ✅ Хорошо
allow_methods=["GET", "POST", "DELETE", "PUT"]
Как отладить CORS
- Откройте DevTools (F12)
- Перейдите на вкладку Network
- Посмотрите заголовки запроса и ответа
- Проверьте консоль на ошибки
- Убедитесь, что сервер отправляет нужные
Access-Control-*заголовки
КОРС — это механизм безопасности браузера, который требует явного разрешения сервера на кросс-доменные запросы.