CORS hatası neden çıkar ve doğru çözüm nedir?
"blocked by CORS policy" mesajı, ön yüzden bir API çağırırken en sık karşılaşılan hatalardan biri. Sorun genelde ön yüzde değil, API'nin verdiği cevapta.
CORS ne işe yarar?
Tarayıcılar güvenlik için aynı köken politikası uygular: https://site-a.com üzerinde çalışan JavaScript, https://api.site-b.com'a istek atabilir ama cevabı okuyamaz, meğer ki API buna açıkça izin versin. Köken; protokol, alan adı ve porttan oluşur. http://localhost:3000 ile http://localhost:8000 farklı kökenlerdir.
CORS bu izni vermenin yoludur: API cevabına özel başlıklar ekler.
Temel başlıklar
Access-Control-Allow-Origin: https://site-a.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Preflight (ön kontrol) isteği
İstek "basit" değilse (örneğin Content-Type: application/json veya Authorization başlığı varsa) tarayıcı önce bir OPTIONS isteği gönderir. API bu isteğe yukarıdaki başlıklarla 2xx dönmezse asıl istek hiç gönderilmez. Network sekmesinde başarısız bir OPTIONS isteği görüyorsan sorun buradadır.
Doğru çözüm: sunucu tarafında izin ver
Express (Node.js):
import cors from "cors";
app.use(cors({ origin: "https://site-a.com", credentials: true }));
Nginx:
add_header Access-Control-Allow-Origin "https://site-a.com" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
if ($request_method = OPTIONS) { return 204; }
Çoğu çatının (Django, Laravel, Symfony, Spring, ASP.NET) kendi CORS ayarı veya paketi vardır; elle başlık yazmak yerine onları kullan.
Yapılmaması gerekenler
Access-Control-Allow-Origin: *ile çerezli istek: Tarayıcı, kimlik bilgisi (çerez) taşıyan isteklerde*değerini kabul etmez. Kökeni açıkça yaz.- Gelen Origin'i körü körüne geri yansıtmak: Her kökene izin vermek, başka siteleri senin kullanıcın adına API çağırabilir hâle getirebilir. İzinli kökenleri bir listede tut.
- Tarayıcı eklentisiyle CORS'u kapatmak: Sadece senin bilgisayarında çalışır, sorunu çözmez.
Geliştirme ortamında pratik yol
Vite, webpack gibi araçların proxy ayarı, ön yüzden giden istekleri aynı köken üzerinden API'ye iletir. Böylece geliştirirken CORS'a takılmazsın; canlıda yine doğru başlıkları ayarlaman gerekir.
Hata alıyorsan konsoldaki tam mesajı ve Network sekmesindeki istek/cevap başlıklarını paylaşırsan nedeni bulmak kolaylaşır.