5.3 KiB
Решение CORS Error
Что такое CORS?
CORS (Cross-Origin Resource Sharing) - это механизм безопасности браузера, который блокирует запросы между разными доменами/портами.
Проблема
При разработке:
- Frontend (Flutter Web) работает на
http://localhost:xxxxx(случайный порт) - Backend работает на
http://localhost:8000 - Браузер блокирует запросы между этими портами
Решение
1. ✅ Backend настроен (исправлено 19 окт 2025)
В файле mnemo_cards_backend/lib/api/mnemo_shelf.dart добавлена правильная CORS конфигурация:
final corsConfig = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS',
'Access-Control-Allow-Headers': 'Origin, Content-Type, Accept, Authorization, user_token, request_token, app_version',
'Access-Control-Expose-Headers': 'Authorization',
'Access-Control-Max-Age': '86400',
};
⚠️ ВАЖНО: CORS middleware должен быть ПЕРВЫМ в pipeline, иначе preflight запросы (OPTIONS) будут блокироваться авторизацией:
final handler = Pipeline()
.addMiddleware(corsHeaders(headers: corsConfig)) // ← CORS ПЕРВЫМ!
.addMiddleware(logRequests(logger: logger('app')))
.addMiddleware(appAuthorize(getIt.get<UserManager>()))
.addHandler(rootRouter);
Это позволяет:
- ✅ Принимать запросы с любого origin (
*) - ✅ Разрешает все необходимые HTTP методы
- ✅ Разрешает кастомные заголовки (
user_token,request_token,app_version) - ✅ Разрешает читать заголовок
Authorizationв ответе - ✅ OPTIONS запросы обрабатываются до проверки авторизации
2. 🚀 Запуск Backend
Используйте скрипт для запуска backend в режиме разработки:
cd /Users/dmitry/StudioProjects/mnemo_cards/mnemo_cards_backend
./run_dev.sh
Backend будет доступен на http://localhost:8000
3. 🌐 Запуск Frontend
В отдельном терминале запустите веб-версию:
cd /Users/dmitry/StudioProjects/mnemo_cards/mnemo_cards_web_v2
flutter run -d chrome
4. ✔️ Проверка
После запуска обоих сервисов:
- Откройте DevTools в Chrome (F12)
- Перейдите на вкладку Network
- Проверьте что запросы к
/packs/previews,/gamesи т.д. успешны - В заголовках ответа должны быть CORS заголовки
Альтернативные решения (если не помогло)
Вариант 1: Отключить web security в Chrome (только для разработки!)
# macOS
open -n -a "Google Chrome" --args --user-data-dir="/tmp/chrome_dev_session" --disable-web-security
# Linux
google-chrome --disable-web-security --user-data-dir="/tmp/chrome_dev_session"
⚠️ Внимание: Это небезопасно! Используйте только для разработки.
Вариант 2: Использовать Flutter с --web-port
Запускайте Flutter на фиксированном порту:
flutter run -d chrome --web-port=8080
Вариант 3: Production CORS (для деплоя)
Для production версии:
- Backend уже настроен с правильными CORS настройками ✅
- Frontend использует
https://api.mnemo-cards.online(nginx:443) ✅ - Nginx настроен без конфликтующих COEP/COOP headers ✅
Текущая конфигурация позволяет:
- ✅ Запросы с
memo-cards.onlineнаhttps://api.mnemo-cards.online - ✅ Все необходимые HTTP методы и headers
- ✅ Preflight OPTIONS запросы
Диагностика
Если CORS ошибка все еще возникает:
-
Проверьте что backend запущен:
curl http://localhost:8000/games -
Проверьте CORS заголовки:
curl -H "Origin: http://localhost:8080" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: X-Requested-With" -X OPTIONS --verbose http://localhost:8000/games -
Посмотрите логи backend - там будут видны все входящие запросы
-
Проверьте что ApiConfig использует правильный URL:
// В lib/domain/config/api_config.dart static const String baseUrl = 'http://localhost:8000';