Rehberler

CORS Hataları Nasıl Düzeltilir (ve Neden Oluşurlar)

CORS hatası, web sayfanızın farklı bir kökenden (başka bir alan adı, port ya da protokol) bir yanıtı okumaya çalıştığı, ama o sunucunun buna izin verildiğini bildiren başlıklar göndermediği anlamına gelir. Tarayıcılar kullanıcıyı korumak için yanıtı engeller. Düzeltmeyi sunucuda yaparsınız: sitenizin kökeni için bir Access-Control-Allow-Origin başlığı döndürerek ve OPTIONS ön uçuş isteklerini yöneterek; ya da isteği aynı köken üzerindeki kendi arka ucunuz üzerinden göndererek bundan kaçınırsınız.

Geliştirmede en kafa karıştırıcı hatalardan biridir, çünkü istek çoğu zaman sunucuya sorunsuz ulaşır. Bu rehber neyin olduğunu ve her türün nasıl düzeltileceğini açıklar.

“Köken” ne demek

Köken, protokol, alan adı ve portun birleşimidir:

URLKöken
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (farklı alt alan adı, dolayısıyla farklı köken)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (farklı port, dolayısıyla farklı köken)

Tarayıcılar aynı köken politikasını izler: bir sayfadaki JavaScript kendi kökeninden gelen yanıtları serbestçe okuyabilir, ama diğerlerinden okuyamaz. CORS (Cross-Origin Resource Sharing), bir sunucunun buna katılmasını sağlayan sistemdir: “Bana ait yanıtları bu kökenlerdeki sayfalar okuyabilir.”

İnsanları şaşırtan iki sonuç vardır:

  • İstek çoğu zaman sunucuya ulaşır. CORS genellikle sunucunun isteği almasını değil, kodunuzun yanıtı okumasını engeller. Bir hata gördüğünüz halde bir POST kaydedilmiş olabilir.
  • Yalnızca tarayıcılar uygular. curl, Postman ve sunucu tarafı kod CORS’u tamamen yok sayar. Bu yüzden “Postman’de çalışıyor” CORS hakkında hiçbir şey söylemez.

Adım 1: Tam hatayı okuyun

Geliştirici araçlarını açın (sağ tık → İncele), Konsol sekmesine gidin ve tam mesajı okuyun. Chrome’un ifadesi hangi sorunu yaşadığınızı söyler:

Mesaj şunu içeriyorsaYanlış olan
No 'Access-Control-Allow-Origin' header is presentSunucu bu başlığı hiç göndermedi ya da istek CORS kodunuza ulaşmadan başarısız oldu (örneğin 404 ya da 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originSunucu sizin kökeninizden farklı bir köken için izin veriyor
Response to preflight request doesn't pass access control checkOPTIONS ön uçuş isteği başarısız oldu
...must not be the wildcard '*' when the request's credentials mode is 'include'Çerez gönderiyorsunuz ve sunucu * ile yanıt verdi
Request header field authorization is not allowedSunucu bu başlığı Access-Control-Allow-Headers içinde listelemedi

Sonra Ağ sekmesini açın, başarısız isteği (ve öncesindeki varsa OPTIONS isteğini) bulun ve durum kodunu ve yanıt başlıklarını inceleyin.

Önce durum koduna bakın. Birçok “CORS hatası” aslında gizlenmiş bir sunucu hatasıdır. Sunucu çöker ya da 404 dönerse, hata yanıtı çoğu zaman CORS başlıklarını içermez, bu yüzden tarayıcı gerçek sorun yerine CORS bildirir. 500 ya da 404’ü düzeltin; CORS hatası da kaybolabilir.

Adım 2: Bu API’yi gerçekten tarayıcıdan çağırmanız gerekip gerekmediğine karar verin

Başlık eklemeden önce sorun: tarayıcı bu API’yi doğrudan çağırmalı mı?

  • Gizli anahtar gerektiren bir üçüncü taraf API’si (OpenAI, Stripe gizli anahtarı, çoğu e-posta hizmeti) asla tarayıcıdan çağrılmamalıdır. Anahtar her ziyaretçiye görünür olur. Bunun yerine arka ucunuzdan çağırın; sunucudan sunucuya istekler CORS’a tabi olmadığı için CORS sorunu ortadan kalkar. Bkz. API anahtarlarını güvende tutma.
  • Kontrol etmediğiniz, CORS başlıkları göndermeyen bir üçüncü taraf API’si sizin tarafınızdan düzeltilemez. Arka ucunuzdan çağırın.
  • Kendi API’niz, uygun şekilde yapılandırılarak düzeltilebilir. Aşağıya devam edin.

Adım 3: Sunucunuzda düzeltin

Sunucu, hata yanıtları dahil tüm yanıtlarına doğru başlıkları eklemelidir.

Asıl istek için şunu gönderin:

  • Access-Control-Allow-Origin: https://myapp.com (ön yüzünüzün tam kökeni, sonunda eğik çizgi olmadan)
  • Değer, isteği hangi kökenin yaptığına bağlıysa Vary: Origin

Ön uçuş OPTIONS isteği için başarılı bir durum kodu (200 ya da 204) ile şunları döndürün:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (gönderdiğiniz her özel başlık)
  • İsteğe bağlı olarak Access-Control-Max-Age: 600, böylece tarayıcı ön uçuş yanıtını bir süre önbelleğe alır

Çoğu çatının bunu yapan bir paketi ya da ayarı vardır. Express’te cors paketi; FastAPI’de CORSMiddleware; ASP.NET Core’da AddCors; Spring’de @CrossOrigin ya da bir CORS yapılandırması. Tipik bir Express kurulumu:

import cors from "cors";

app.use(cors({
  origin: ["https://myapp.com", "http://localhost:5173"],
  credentials: true,
}));

CORS işlemesini rotalarınızdan ve kimlik doğrulamadan önce koyun; böylece giriş bilgisi taşımayan ön uçuş istekleri 401 ile reddedilmez.

Bir yapay zeka oluşturucuyla çalışıyorsanız, kurulumu kesin olarak tarif edin:

https://myapp.com adresindeki ön yüz https://api.myapp.com adresindeki API’yi çağırıyor ve “Response to preflight request doesn't pass access control check” hatası alıyor. API’de CORS’u tam olarak https://myapp.com ve önizleme kökenine izin verecek şekilde yapılandır; Content-Type ve Authorization başlıklarıyla GET, POST, PATCH, DELETE’e izin ver; OPTIONS isteklerini kimlik doğrulamadan önce işle; hata yanıtlarına da CORS başlıkları ekle.

Adım 4: Çerezleri ve kimlik bilgilerini yönetin

Ön yüzünüz başka bir kökene çerez (örneğin bir giriş oturumu) gönderiyorsa, iki taraf da uyuşmalıdır:

  • Ön yüz, fetch üzerinde credentials: "include" ya da axios’ta withCredentials: true ayarlar.
  • Sunucu Access-Control-Allow-Credentials: true gönderir.
  • Sunucunun Access-Control-Allow-Origin değeri * değil, tam köken olmalıdır.

Siteler arası çerezler için çerezde ayrıca SameSite=None; Secure gerekir ve bazı tarayıcılar üçüncü taraf çerezlerini daha da kısıtlar. Bu, Adım 5’teki yaklaşımı tercih etmek için bir neden daha.

Adım 5: Aynı köken kurulumuyla CORS’tan kaçının

Çoğu zaman en temiz düzeltme, hiç köken ötesi istek yapmamaktır. API’yi sayfayla aynı kökenden sunun, örneğin https://myapp.com/api/... adresinde:

  • Geliştirmede, çoğu geliştirme sunucusu proxy yapabilir. Vite’ın server.proxy ayarı /api isteklerini farklı bir porttaki arka ucunuza iletebilir; böylece tarayıcı yalnızca tek bir kökenle konuşur.
  • Üretimde, /api isteklerini sunucunuzun rewrite ya da proxy ayarlarıyla arka uca yönlendirin ya da ön yüzü ve API’yi tek bir sunucudan sunun.

Ön yüz daha sonra fetch("/api/orders") gibi göreceli bir yolu çağırır. Köken ötesi istek, köken ötesi ön uçuş ve çerez baş ağrısı kalmaz. Ayrıca önizleme ile üretim arasında farklılık gösteren bir API alan adını sabit kodlamanız gerekmez.

Ön yüzü, tam URL yerine göreceli /api yollarıyla arka ucu çağıracak şekilde değiştir ve /api isteklerini API sunucusuna ileten bir geliştirme proxy’si kur. Sonra artık ihtiyaç olmayan CORS ayarlarını kaldır.

Yapmamanız gerekenler

  • fetch içinde mode: "no-cors". Hiçbir şeyi aşmaz; kodunuza boş ve okunamaz bir yanıt verir.
  • CORS’u devre dışı bırakan tarayıcı eklentileri. Yalnızca kendi tarayıcınızı değiştirirler. Her ziyaretçi hatayı görmeye devam eder.
  • Gerçek uygulamalar için genel “CORS proxy” hizmetleri. Üzerlerinden geçen her şeyi okuyup değiştirebilirler ve çökebilirler.
  • Girişli bir API’de Access-Control-Allow-Origin: *. Zaten kimlik bilgileriyle çalışmaz ve özel veriler için yanlış varsayılandır.
  • Kimlik bilgilerine izin verirken herhangi bir Origin başlığını geri yansıtmak. Bu, herhangi bir web sitesinin kullanıcılarınız adına giriş yapılmış istekler göndermesine izin verir. Bir izin listesi kullanın.

Yapay zeka ile yapılmış uygulamalarda sık nedenler

DurumDüzeltme
Ön yüz, gizli anahtarlı bir üçüncü taraf API’sini çağırıyorÇağrıyı arka uca taşıyın
Önizlemede çalışıyor, yayınlanmış alan adında başarısızYayınlanmış ve özel alan adı kökenlerini izin listesine ekleyin ya da göreceli /api yollarını kullanın
Yalnızca POST, PUT ya da DELETE’te hataÖn uçuş işlenmiyor; OPTIONS işlemesi ve izin verilen başlıklar ekleyin
Giriş eklendikten sonra hata çıktıKimlik bilgileri tam köken ve Allow-Credentials gerektirir
“CORS hatası” ama Ağ sekmesinde 500 görünüyorÖnce sunucu hatasını düzeltin
API URL’si localhost olarak sabit kodlanmışGöreceli yollar ya da ortama özel bir ayar kullanın

Mythex’te CORS

Bir Mythex projesinde bir web sitesi ve bir API sunucusu varsa, ikisi de aynı projede hizmet olarak çalışır ve önizlemede aralarında geçiş yapabilirsiniz. Ajandan, ön yüzün arka ucu göreceli bir /api yolu üzerinden çağırmasını istemek (geliştirmede proxy’lenerek) CORS sorunlarının çoğundan kaçınır. Köken ötesi çağrılara gerçekten ihtiyacınız varsa, ajana konsoldaki tam hatayı ve ilgili kökenleri verin. Yayınlanmış uygulamanın adresi önizlemedekinden farklı olduğu için sonucu onda da kontrol edin. Dokümanlarda Çoklu hizmet uygulamaları ve API arka uçları bölümlerine, ayrıca yapay zekayla yapılmış bir uygulamada hata ayıklama ve ön yüz ile arka uç rehberlerimize bakın.

CORS kontrol listesi

  • Konsoldaki tam hata ve başarısız isteğin durum kodu okundu
  • Gizli bir 404 ya da 500 olmadığı doğrulandı
  • Gizli anahtarlı API’ler tarayıcıdan değil arka uçtan çağrılıyor
  • Sunucu, tam izin verilen kökenlerle Access-Control-Allow-Origin gönderiyor
  • OPTIONS ön uçuşu, kimlik doğrulamadan önce izin verilen yöntemler ve başlıklarla yanıtlanıyor
  • Hata yanıtlarında da CORS başlıkları var
  • Kimlik bilgileri: tam köken, Allow-Credentials: true, doğru çerez ayarları
  • Önizleme, yayınlanmış ve özel alan adı kökenlerinin hepsi kapsanıyor ya da göreceli /api yolları kullanılıyor
  • no-cors, genel proxy’ler ya da her kökeni yansıtma kısayolları yok

Sorular

CORS hatası ne anlama gelir?

Bir kökenden yüklenen sayfanız, farklı bir kökenden bir yanıtı okumaya çalıştı; o sunucunun yanıtında buna izin veren başlıklar yoktu. Tarayıcı kodunuzun yanıtı okumasını engeller. Düzeltme sunucudadır ya da isteğin nasıl yönlendirildiğindedir, ön yüz kodunda değil.

CORS hatasını ön yüzden düzeltebilir miyim?

Doğru şekilde düzeltemezsiniz. mode: 'no-cors' gibi ayarlar yanıtı yalnızca kodunuzdan gizler. Düzeltmek için sunucunun doğru Access-Control-Allow-Origin başlığını göndermesini sağlarsınız ya da API’yi kendi arka ucunuzdan ya da aynı köken bir proxy üzerinden çağırırsınız.

Access-Control-Allow-Origin: * güvenli mi?

Girişi olmayan bir genel API gibi, herkesin okuyabileceği genel veriler için uygundur. Çerezler ya da diğer kimlik bilgileriyle kullanılamaz; özel API’ler için izin verilen kökenleri tek tek listelemelisiniz.

İsteğim Postman ya da curl’de çalışıyor ama tarayıcıda çalışmıyor, neden?

CORS yalnızca tarayıcılar tarafından uygulanır. Postman ve curl gibi araçlar bunu uygulamaz; bu yüzden bir istek orada başarılı olabilir, ama sayfanın JavaScript’i isteği gönderdiğinde engellenebilir.

Ön uçuş (preflight) isteği nedir?

JSON POST gibi basit olmayan ya da Authorization başlığı içeren isteklerde tarayıcı önce hangi yöntemlere ve başlıklara izin verildiğini soran bir OPTIONS isteği gönderir. Bu OPTIONS isteği başarısız olur ya da doğru başlıkları içermezse, asıl istek hiç gönderilmez.

Mythex · Pricing · Yapay zekayla her şeyi yapın · Web sitesi ve uygulama şablonları · Mythex karşılaştırmaları · Yapay zekayla uygulama geliştirme sözlüğü · Yapay zekayla uygulama geliştirme için ücretsiz araçlar · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)