Emre

WFN Üye
Konular
1,664
Mesajlar
1,760
Çözüm
0
Ticaret Puanı
0
Üyelik
9 Ay 4 Gün
Konum
Samsun
Web Sitesi
Var
Alanı
WordPress Uzm.
1/1
Konu sahibi
JavaScript’te CORS hatası, tarayıcının bir web sayfasının farklı bir kaynakta bulunan API’ye erişmesine izin vermemesiyle oluşur. Çözüm, JavaScript kodunu zorlayarak tarayıcı güvenliğini aşmak değil, API sunucusunun isteği gönderen kaynağa uygun CORS yanıt başlıklarını döndürmesini sağlamaktır. Geliştirme ortamında istemci adresini sunucuda izin verilen kaynak olarak tanımlayın; üretimde ise yalnızca gerçekten kullanacağınız alan adlarına izin verin.

Önce hatanın nerede oluştuğunu belirleyin​


Tarayıcı geliştirici araçlarında Network veya Console bölümünü açıp başarısız isteği inceleyin. Hata genellikle şu anlama gelir: API yanıtında Access-Control-Allow-Origin başlığı yoktur, değeri mevcut sayfanın kaynağıyla eşleşmiyordur ya da tarayıcı önce yaptığı ön kontrol isteğine (OPTIONS) beklenen yanıtı alamıyordur.

Kaynak; protokol, alan adı ve portun birlikte oluşturduğu adrestir. Örneğin http://localhost:3000 ile http://localhost:5173 farklı kaynaklardır. Bu nedenle API localhost:8000 üzerinde çalışsa bile, istemcinin çalıştığı port için ayrıca izin gerekebilir.

CORS hatası yalnızca tarayıcıdaki çapraz kaynak erişimini sınırlar. İsteği Postman veya cURL ile gönderebilmeniz, tarayıcıdaki JavaScript kodunun da erişebileceğini kanıtlamaz; bu araçlar aynı tarayıcı güvenlik politikasını uygulamaz.

Çözüm sunucuda yapılır​


API sizin kontrolünüzdeyse, sunucunun istemcinin gerçek kaynağını kabul etmesini sağlayın. Örneğin istemci http://localhost:3000 adresinde, API ise Node.js ve Express üzerinde çalışıyorsa CORS ara yazılımını sunucuya ekleyebilirsiniz:

JavaScript:
const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors({
  origin: 'http://localhost:3000',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

app.get('/api/veriler', (req, res) => {
  res.json({ mesaj: 'İstek kabul edildi' });
});

app.listen(8000, () => {
  console.log('API 8000 portunda çalışıyor');
});

Bu örnekte tarayıcıdaki uygulama http://localhost:3000 adresinden http://localhost:8000/api/veriler adresine istek gönderebilir. İstemci kodu şöyle olabilir:

JavaScript:
fetch('http://localhost:8000/api/veriler')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP hatası: ${response.status}`);
    }
    return response.json();
  })
  .then(veri => console.log(veri))
  .catch(hata => console.error(hata));

Sunucuyu yeniden başlatıp isteği tekrar gönderdiğinizde yanıt tarayıcıya ulaşırsa CORS sorunu çözülmüştür. Network bölümünde API yanıtının Access-Control-Allow-Origin: http://localhost:3000 başlığını içerdiğini de kontrol edebilirsiniz. Bu başlığın görünmesi tek başına API’nin doğru veri döndürdüğünü kanıtlamaz; yalnızca tarayıcının yanıtı istemci koduna açmasına izin verildiğini gösterir.

Kullanılan teknolojiye göre temel ayar​


CORS ayarının yeri kullandığınız sunucu teknolojisine göre değişir. Amaç her durumda aynıdır: İstek kaynağını, HTTP yöntemini ve gerekiyorsa özel başlıkları sunucunun kabul etmesini sağlamak.
DurumSunucuda yapılacak işlemDikkat edilecek nokta
Basit GET isteğiYanıta uygun Access-Control-Allow-Origin başlığı eklenirDeğer, sayfanın gerçek kaynağıyla eşleşmelidir
POST, PUT veya DELETE isteğiKullanılan yöntemler CORS yapılandırmasına eklenirSunucu yöntemi gerçekten işliyor olmalıdır
Authorization veya özel Content-Typeİzin verilen başlıklara eklenirÖn kontrol OPTIONS isteği de yanıtlanmalıdır
Çerez veya oturum bilgisiİstemci ve sunucuda kimlik bilgisi gönderimi etkinleştirilirAllow-Origin değeri yıldız (*) olamaz
İstemci Authorization gibi özel bir başlık gönderiyorsa tarayıcı çoğu durumda önce OPTIONS isteği yapar. Sunucu bu isteğe başarılı bir HTTP durum kodu ve gerekli CORS başlıklarıyla yanıt vermelidir. OPTIONS isteği 404, 405 veya 500 dönüyorsa asıl GET ya da POST isteği çalışmadan engellenebilir.

Çerez ve kimlik doğrulama kullanılıyorsa​


Oturum çerezi gönderilecekse istemci isteğinde kimlik bilgilerini açıkça belirtin:

JavaScript:
fetch('https://api.ornek.com/profil', {
  credentials: 'include'
});

Sunucu da Access-Control-Allow-Credentials: true göndermelidir. Bu durumda Access-Control-Allow-Origin: * kullanılamaz; sunucu belirli istemci kaynağını açıkça belirtmelidir. Çerezlerin SameSite, Secure ve alan adı ayarları da ayrıca uygun olmalıdır. CORS başlıkları doğru olsa bile çerez politikası uygun değilse oturum bilgisi gönderilmeyebilir.

Çalışmayan yaklaşımlar ve doğru sonraki adım​


JavaScript içinde mode: 'no-cors' kullanmak genel bir çözüm değildir. İstek gönderilebilir ancak yanıt çoğunlukla opak olur; JavaScript yanıt gövdesini ve normal HTTP bilgilerini okuyamaz. Bu seçenek, API verisini uygulama içinde kullanabilmeniz için CORS sorununu çözmez.

Tarayıcı eklentisiyle CORS denetimini kapatmak da yalnızca kendi bilgisayarınızdaki geçici geliştirme testi için kullanılabilir. Kullanıcıların tarayıcı ayarını değiştirmesini gerektiren bir uygulama yayımlanamaz. Üretim çözümü API sunucusunda veya kendi sunucunuzdaki güvenilir bir ara katmanda yapılmalıdır.

API size ait değilse ve karşı taraf CORS izni vermiyorsa, doğrudan tarayıcıdan istek göndermek yerine sunucu tarafında bir proxy kullanabilirsiniz. Tarayıcı kendi sunucunuza istek gönderir; kendi sunucunuz da API’ye sunucu-sunucu bağlantısı kurup gerekli veriyi döndürür. Proxy, erişim yetkisini veya API anahtarını kullanıcıya açmamalı; gelen adresleri sınırsız biçimde başka sunuculara aktaran açık bir yönlendiriciye dönüştürülmemelidir.

Son kontrol sırasında şu ayrımı yapın:
  • Yanıtta CORS başlığı yoksa veya kaynak eşleşmiyorsa sunucunun izin verilen kaynak ayarını düzeltin.
  • OPTIONS isteği başarısızsa preflight yönlendirmesini, HTTP yöntemlerini ve özel başlık izinlerini kontrol edin.
  • CORS başlıkları doğru olduğu hâlde 401 veya 403 alıyorsanız sorun artık CORS değil, kimlik doğrulama ya da yetkilendirmedir.
  • Sunucu 500 döndürüyorsa önce sunucu hatasını çözün; CORS mesajı asıl uygulama hatasını gizliyor olabilir.
  • İstek başarılı görünüyor fakat çerez gitmiyorsa credentials ve çerez politikalarını birlikte inceleyin.
Üretime geçerken localhost kaynağını bırakıp gerçek istemci alan adını açıkça tanımlayın. Geliştirme kolaylığı için tüm kaynaklara * izni vermek, özellikle kimlik doğrulamalı API’lerde güvenli bir üretim yapılandırması değildir.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic