mnemo_cards/mnemo_cards_web_v2/CORS_FIX.md
2025-11-16 15:15:21 +03:00

5.3 KiB
Raw Blame History

Решение 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. ✔️ Проверка

После запуска обоих сервисов:

  1. Откройте DevTools в Chrome (F12)
  2. Перейдите на вкладку Network
  3. Проверьте что запросы к /packs/previews, /games и т.д. успешны
  4. В заголовках ответа должны быть 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 версии:

  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 запросы

Диагностика

Если CORS ошибка все еще возникает:

  1. Проверьте что backend запущен:

    curl http://localhost:8000/games
    
  2. Проверьте 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
    
  3. Посмотрите логи backend - там будут видны все входящие запросы

  4. Проверьте что ApiConfig использует правильный URL:

    // В lib/domain/config/api_config.dart
    static const String baseUrl = 'http://localhost:8000';
    

Полезные ссылки