Nowy frontend React nie mógł komunikować się z Magento REST API. Każde żądanie AJAX kończyło się błędem CORS w konsoli przeglądarki. Backend działał poprawnie gdy testowano przez Postman lub curl. Czas naprawy: 2 godziny.
Objawy
- Konsola przeglądarki:
Access to fetch has been blocked by CORS policy - Preflight OPTIONS request zwraca brak nagłówka
Access-Control-Allow-Origin - API działa przez Postman i curl – problem tylko w przeglądarce
- Frontend na innej domenie niż Magento API
Rozwiązanie
# Konfiguracja CORS w nginx dla Magento API
# /etc/nginx/conf.d/magento.conf
location /rest/ {
# Obsłuż preflight OPTIONS
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://frontend.sklep.pl' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
add_header 'Access-Control-Max-Age' 86400;
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' 'https://frontend.sklep.pl' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
# Reszta konfiguracji Magento...
try_files $uri $uri/ /index.php?$args;
}
<?php
// Alternatywnie: plugin PHP który dodaje nagłówki CORS
class CorsPlugin
{
public function afterDispatch(
\Magento\Framework\App\FrontControllerInterface $subject,
$result,
\Magento\Framework\App\RequestInterface $request
) {
$allowedOrigins = ['https://frontend.sklep.pl', 'https://app.sklep.pl'];
$origin = $request->getHeader('Origin') ?? '';
if (in_array($origin, $allowedOrigins)) {
$response = \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Framework\App\ResponseInterface::class);
$response->setHeader('Access-Control-Allow-Origin', $origin, true);
$response->setHeader('Access-Control-Allow-Credentials', 'true', true);
}
return $result;
}
}
Wnioski
CORS musi być skonfigurowany po stronie serwera – przeglądarka wymaga jawnego zezwolenia od API. Nie używaj Access-Control-Allow-Origin: * z Access-Control-Allow-Credentials: true – przeglądarka to zablokuje. Zawsze podawaj konkretne domeny frontendowe na whiteliście.
