mnemo_cards/mnemo_cards_web_v2/CORS_FIX.md

138 lines
5.3 KiB
Markdown
Raw Normal View History

2025-11-10 23:55:41 +00:00
# Решение 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 конфигурация:
```dart
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) будут блокироваться авторизацией:
```dart
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 в режиме разработки:
```bash
cd /Users/dmitry/StudioProjects/mnemo_cards/mnemo_cards_backend
./run_dev.sh
```
Backend будет доступен на `http://localhost:8000`
### 3. 🌐 Запуск Frontend
В отдельном терминале запустите веб-версию:
```bash
cd /Users/dmitry/StudioProjects/mnemo_cards/mnemo_cards_web_v2
flutter run -d chrome
```
### 4. ✔️ Проверка
После запуска обоих сервисов:
1. Откройте DevTools в Chrome (F12)
2. Перейдите на вкладку Network
3. Проверьте что запросы к `/packs/previews`, `/games` и т.д. успешны
4. В заголовках ответа должны быть CORS заголовки
## Альтернативные решения (если не помогло)
### Вариант 1: Отключить web security в Chrome (только для разработки!)
```bash
# 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 на фиксированном порту:
```bash
flutter run -d chrome --web-port=8080
```
### Вариант 3: Production CORS (для деплоя)
2025-11-16 12:15:21 +00:00
Для production версии:
2025-11-10 23:55:41 +00:00
2025-11-16 12:15:21 +00:00
1. **Backend** уже настроен с правильными CORS настройками ✅
2. **Frontend** использует `api.memo-cards.online`
3. **Nginx** настроен без конфликтующих COEP/COOP headers ✅
Текущая конфигурация позволяет:
- ✅ Запросы с `memo-cards.online` на `api.memo-cards.online`
-Все необходимые HTTP методы и headers
- ✅ Preflight OPTIONS запросы
2025-11-10 23:55:41 +00:00
## Диагностика
Если CORS ошибка все еще возникает:
1. **Проверьте что backend запущен**:
```bash
curl http://localhost:8000/games
```
2. **Проверьте CORS заголовки**:
```bash
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
```
3. **Посмотрите логи backend** - там будут видны все входящие запросы
4. **Проверьте что ApiConfig использует правильный URL**:
```dart
// В lib/domain/config/api_config.dart
static const String baseUrl = 'http://localhost:8000';
```
## Полезные ссылки
- [MDN: CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
- [shelf_cors_headers package](https://pub.dev/packages/shelf_cors_headers)
- [Flutter Web: CORS](https://docs.flutter.dev/platform-integration/web/building#handling-cors-errors-only-applicable-to-web)