ENBirlikte üretelim
← Argo Ajans

Kurumsal Yazılım

CORS hatası nasıl çözülür? Adım adım rehber

Mehmet Said Göksu ·

CORS hatası nasıl çözülür? Adım adım rehber

Kısa yanıt

CORS hatası, tarayıcının farklı bir alan adına (origin) gönderdiği bir isteğin yanıtını, sunucu buna açıkça izin vermediği için JavaScript koduna göstermemesidir; bu bir bağlantı kopması değil, tarayıcının aynı-köken güvenlik politikasının bilinçli bir uyarısıdır. Çözüm hemen hemen her zaman frontend tarafında değil, API’yi sunan backend’de doğru Access-Control-Allow-Origin başlığını döndürmektir.

CORS hatası neden oluşur ve mantığı nedir?

Tarayıcılar, varsayılan olarak bir sayfadaki JavaScript kodunun başka bir origin’e (farklı şema, alan adı veya port) istek göndermesine izin verir, ancak bu isteğin yanıtını okumasına izin vermez; bu kural aynı-köken politikası (same-origin policy) olarak bilinir. CORS (Cross-Origin Resource Sharing), sunucunun “bu origin’den gelen isteklerin yanıtımı okumasına izin veriyorum” demesini sağlayan bir mekanizmadır. Sunucu bu izni özel HTTP başlıklarıyla vermezse, tarayıcı isteği engellemez ama yanıtı kodunuzdan gizler ve konsola CORS hatası basar.

Bu ayrım pratikte çok önemlidir: istek sunucuya genellikle ulaşır, sunucu da yanıtı üretir; sorun ağ katmanında değil, tarayıcının yanıtı size göstermeyi reddetmesindedir. Bu yüzden bir CORS hatasıyla karşılaşan geliştiricilerin ilk refleksi genellikle “sunucum çalışmıyor” olur, ama gerçek neden hemen hemen her zaman eksik veya yanlış yapılandırılmış bir CORS başlığıdır. Frontend’deki fetch veya axios çağrısını değiştirmek, kodu sunucudan ayrı bir origin’de barındırdığınız sürece bu hatayı çözmez.

CORS hatası özellikle şu senaryolarda sık görülür: frontend localhost:3000’de çalışırken API localhost:8000’de veya farklı bir alan adında barındırıldığında; bir mobil uygulamanın web görünümü ayrı bir domain üzerinden API çağırdığında; ya da bir WordPress sitesinin headless bir frontend’e (Next.js, React gibi) REST API üzerinden veri sağladığında. Port numarası farklı olsa bile tarayıcı bunu ayrı bir origin sayar; http://site.com ile https://site.com da birbirinden farklı origin’dir.

Tarayıcı konsolunda hangi mesajları görürsünüz?

Mesaj Tipik neden İlk çözüm
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource Sunucu hiç CORS başlığı döndürmüyor Backend’e doğru Access-Control-Allow-Origin başlığını ekleyin
Response to preflight request doesn't pass access control check OPTIONS (preflight) isteğine doğru yanıt verilmiyor Sunucunun OPTIONS’u 200/204 ve doğru başlıklarla yanıtlamasını sağlayın
...must not be the wildcard '*' when the request's credentials mode is 'include' credentials: 'include' ile wildcard origin birlikte kullanılıyor Wildcard yerine isteğin geldiği origin’i açıkça döndürün
No 'Access-Control-Allow-Headers' header is present İstekte özel bir başlık (ör. Authorization) var ama sunucu izin vermiyor İlgili başlığı Access-Control-Allow-Headers listesine ekleyin
net::ERR_FAILED (CORS mesajı hiç görünmüyor) İstek sunucuya hiç ulaşmadı (DNS, SSL, yanlış port) Önce bunun CORS değil bağlantı hatası olduğunu doğrulayın

CORS hatası nasıl çözülür?

1. Hatanın gerçekten CORS olduğunu doğrulayın

Tarayıcının geliştirici araçlarında Network sekmesini açın ve ilgili isteğe bakın. İstek kırmızı görünüyor ve durum kodu hiç yoksa (örneğin (failed)), sorun büyük olasılıkla CORS değil; DNS, SSL sertifikası veya yanlış bir adres/port olabilir. İstek gerçekten sunucuya ulaşıp bir yanıt almışsa ama konsolda CORS ibaresi geçen kırmızı bir mesaj varsa, probleminiz kesinlikle CORS yapılandırmasıdır ve çözüm sunucu tarafındadır.

2. Backend’de doğru Access-Control-Allow-Origin başlığını ekleyin

Node.js/Express kullanan bir API için en basit çözüm cors paketini eklemektir:

Const cors = require('cors');
App.use(cors({ origin: 'https://siteniz.com' }));

Nginx gibi bir ters proxy kullanıyorsanız başlığı sunucu seviyesinde de ekleyebilirsiniz:

Add_header 'Access-Control-Allow-Origin' 'https://siteniz.com' always;

Üretim ortamında origin’i * yerine gerçek alan adınızla sınırlı tutmak, hem güvenlik hem de credentials kullanan isteklerin çalışması için gereklidir.

3. Preflight (OPTIONS) isteğini doğru yanıtlayın

PUT, DELETE, özel başlıklar veya application/json gövdesi taşıyan istekler “basit olmayan” istek sayılır ve tarayıcı önce otomatik bir OPTIONS isteği gönderir. Sunucunuz bu isteğe Access-Control-Allow-Methods ve Access-Control-Allow-Headers başlıklarıyla, genellikle 200 veya 204 durum koduyla yanıt vermelidir; aksi halde tarayıcı asıl isteği hiç göndermeden konsola preflight hatası basar. Bu adım, API’nizi Postman’de test ettiğinizde her şeyin doğru görünmesine ama tarayıcıda hata vermesine neden olan en yaygın sebeptir, çünkü Postman preflight isteği göndermez.

4. Credentials (çerez/oturum) kullanıyorsanız wildcard’dan kaçının

İstekte credentials: 'include' kullanıyorsanız (çerez tabanlı oturum, HttpOnly cookie gibi), sunucunun Access-Control-Allow-Origin başlığında * döndürmesi tarayıcı tarafından geçersiz sayılır; başlıkta isteğin geldiği gerçek origin’in açıkça yazılması ve Access-Control-Allow-Credentials: true başlığının eklenmesi gerekir. Bu ikisini birlikte unutmak, oturum tabanlı API’lerde en sık rastlanan CORS hatasıdır.

Geliştirme ortamında hızlı çözüm: proxy kullanmak

Yerel geliştirme sırasında backend’i değiştirme yetkiniz yoksa veya henüz hazır değilse, frontend tarafında bir geliştirme proxy’si kullanmak pratik bir ara çözümdür. Vite’ta vite.config.js içindeki server.proxy ayarı, webpack’te devServer.proxy ayarı, tarayıcı isteklerini kendi origin’inizden gönderiyormuş gibi gösterip arka planda gerçek API’ye yönlendirir; bu sayede tarayıcı CORS kontrolü yapmaz. Bu çözüm yalnızca geliştirme ortamı içindir; üretimde gerçek çözüm her zaman sunucudaki CORS başlıklarını doğru yapılandırmaktır.

WordPress ve headless projelerde CORS hatası

Bir WordPress sitesini REST API üzerinden ayrı bir frontend’e (Next.js, React, mobil uygulama) veri sağlayan headless bir mimaride kullandığınızda, WordPress çekirdeği varsayılan olarak her origin’e CORS izni vermez. Çözüm, temanın functions.php dosyasında veya küçük bir eklentide rest_api_init kancasına bağlanıp ilgili isteklerde Access-Control-Allow-Origin başlığını elle eklemektir; bazı hosting ortamlarında bu başlığı .htaccess veya sunucu yapılandırmasından eklemek daha güvenilir sonuç verir. Bu konuda WordPress’in kendi hata senaryolarını WordPress veritabanı bağlantısı kurulamadı hatası rehberimizde de ele alıyoruz; CORS, veritabanı hatasından farklı olarak sunucu tamamen çalışırken ortaya çıkan bir yetkilendirme meselesidir.

Güvenlik açısından yapılmaması gerekenler

CORS hatasıyla karşılaşan bazı geliştiriciler, soruna gerçekten bakmadan Access-Control-Allow-Origin: * ile tüm origin’lere izin vermeyi veya tarayıcıda CORS kontrolünü devre dışı bırakan bir eklenti kullanmayı tercih eder. İlki, kimlik doğrulaması gerektiren veya hassas veri döndüren bir API’de güvenlik açığına dönüşebilir; API’niz hangi sitelerin ona istek atabileceğini kontrol edemez hale gelir. İkincisi ise yalnızca sizin tarayıcınızda sorunu gizler, gerçek kullanıcıların tarayıcısında hata devam eder; bu yüzden üretimde asla gerçek bir çözüm sayılmamalıdır.

Sık yapılan hatalar

En yaygın hata, hatayı okumadan frontend kodunu değiştirmeye çalışmaktır; CORS başlıkları sunucu tarafında eklenir, istemci kodunda değil. İkinci sık hata, geliştirme ortamındaki geçici bir proxy veya tarayıcı eklentisi çözümünü üretime taşımaktır. Üçüncüsü, credentials kullanan bir API’de wildcard origin denemektir; bu kombinasyon tarayıcı tarafından doğrudan reddedilir ve hiçbir zaman çalışmaz. Son olarak, preflight isteğini unutup yalnızca asıl isteğe CORS başlığı eklemek de sorunu yarım çözer.

Kontrol listesi

Network sekmesinde isteğin sunucuya gerçekten ulaşıp ulaşmadığını kontrol ederek başlayın. Konsoldaki mesajın hangi başlıktan (origin, headers, credentials) bahsettiğini tam olarak okuyun. Backend’in Access-Control-Allow-Origin başlığını doğru origin ile döndürdüğünü doğrulayın. Basit olmayan isteklerde OPTIONS yanıtının doğru metot ve başlıklarla geldiğini test edin. Credentials kullanıyorsanız wildcard yerine açık origin ve Access-Control-Allow-Credentials: true kullandığınızı teyit edin.

Sonraki adım

CORS hatası, tarayıcının sizi korumaya çalıştığının bir göstergesidir ve doğru başlıklarla genellikle dakikalar içinde çözülür; kritik olan, sorunu frontend’de değil backend’de aramaktır. Şirketinizin API entegrasyonlarını, headless mimarilerini veya mevcut sistemlerle veri alışverişini profesyonel bir altyapıya oturtmak isterseniz, grup şirketimiz Web Tasarım Ofisi bu tür teknik entegrasyon projelerinde uçtan uca destek sağlıyor.

Benzer bağlantı ve dağıtım sorunlarını çözüme kavuşturan ekip desteği için özel yazılım hizmetimizi inceleyebilir ya da bizimle iletişime geçebilirsiniz. Kod gönderimi sırasında karşılaşabileceğiniz farklı bir teknik pürüzü ise git push rejected hatası nasıl çözülür rehberimizde ele alıyoruz.

Kaynaklar

Sıkça sorulan sorular

CORS hatası tam olarak ne anlama gelir?

Tarayıcınızın, farklı bir alan adına (origin) yaptığı isteğin yanıtını okumasına izin verilmediği anlamına gelir. İstek genellikle sunucuya ulaşır ve sunucu yanıt da üretir; engellenen şey ağ trafiği değil, tarayıcının o yanıtı JavaScript koduna göstermesidir.

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

Herkese açık, kimlik doğrulaması gerektirmeyen bir API için genellikle sorun yaratmaz. Ancak istek çerez veya oturum bilgisi taşıyorsa (credentials: 'include'), tarayıcı wildcard origin'i kabul etmez ve isteği doğrudan reddeder; bu durumda origin'i açıkça belirtmeniz gerekir.

Preflight (OPTIONS) isteği nedir, neden CORS hatasına yol açar?

Tarayıcı, basit olmayan isteklerden (özel başlık taşıyan, PUT/DELETE kullanan veya JSON gövdesi gönderen istekler) önce sunucuya otomatik bir OPTIONS isteği gönderir. Sunucu bu isteğe doğru başlıklarla yanıt vermezse tarayıcı asıl isteği hiç göndermez ve konsolda preflight hatası görürsünüz.

CORS hatası yalnızca tarayıcıda mı görülür?

Evet. CORS tamamen tarayıcı tarafında uygulanan bir güvenlik mekanizmasıdır; Postman, cURL veya sunucudan sunucuya yapılan bir istek CORS kısıtlamasına tabi değildir. Bu yüzden bir API'nin Postman'de çalışıp tarayıcıda çalışmaması CORS hatasının en tipik belirtisidir.

WordPress REST API'de CORS hatası nasıl çözülür?

Genellikle tema veya eklenti içindeki rest_api_init kacasına bağlanıp ilgili isteklerde Access-Control-Allow-Origin başlığını elle eklemek gerekir; sunucu seviyesinde .htaccess veya Nginx üzerinden de aynı başlık eklenebilir. Çözüm sitede değil, sunucu veya hosting yapılandırmasındadır.

Bu konuda yardım mı lazım?

Özel Yazılım

Hizmeti inceleyinHemen iletişime geçin
İyi işler, iyi bir konuşmayla başlar.

Birlikte
iz bırakalım.

İzmir ofis
Tariş Cd. (1497. Sok.) No. 5C Ofis P22
35230 Alsancak, İzmir, Türkiye
Birleşik Krallık ofis
167 Sheen Lane
SW14 8NA London, United Kingdom
Kayseri ofis
Sahabiye Mh. Buyurkan Sok. No.29
38015 Kocasinan, Kayseri, Türkiye
Projenizi bize anlatın