Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 6 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi
CORS, bir sayfanın başka bir origin üzerindeki HTTP yanıtını JavaScript ile okuyup okuyamayacağını belirler. iframe ise başka bir belgeyi sayfaya gömmek için kullanılır. Bu nedenle CORS başlığı eklemek, üst sayfanın iframe içindeki DOM'a erişmesini sağlamaz. Iframe görüntülenebilir; ancak iframe farklı origin üzerindeyse üst sayfa contentDocument, document.body veya iframe içindeki değişkenleri okuyamaz.

Önce origin farkını belirleyin​


İki adresin aynı origin sayılması için protokol, alan adı ve portun üçü de aynı olmalıdır. Örneğin aşağıdaki adresler farklı origin'dir:

Kod:
https://example.com
https://www.example.com
http://example.com
https://example.com:8443

Yalnızca yolun değişmesi origin'i değiştirmez. https://example.com/a ile https://example.com/b aynı origin'dir.

Farklı origin'deki iframe'in yüklenmesine genellikle izin verilebilir; fakat tarayıcı üst sayfanın belge içeriğini okumasını Same-Origin Policy ile sınırlar. CORS burada iframe DOM erişimi için değil, örneğin üst sayfadaki fetch() veya XMLHttpRequest çağrısının uzak sunucudan gelen yanıtı okuyabilmesi için kullanılır.

Somut örnek: iframe açılıyor ama DOM okunamıyor​


Bu kurgusal örnek, iki adresi de kontrol edebildiğiniz normal HTTP origin’leri varsayar. Üst sayfanız https://example.com, iframe https://www.example.com/frame.html üzerinde olsun. Karşı tarafın katılımı olmadan herhangi bir uzak siteye mesajlaşma özelliği eklenemez:

Kod:
<iframe id="frame" title="Örnek alt sayfa" src="https://www.example.com/frame.html"></iframe>
<script>
const frame = document.getElementById("frame");
frame.addEventListener("load", () => {
  const doc = frame.contentDocument;
  if (doc === null) {
    console.log("Bu belge üst sayfaya same-origin erişimi vermiyor.");
    return;
  }
  console.log(doc.body.textContent);
});
</script>

Farklı origin durumunda contentDocument null döner; örnek bunu kontrol edip içeriği okumaz. Doğrudan contentWindow.document erişimi ise güvenlik hatası oluşturabilir. Uzak sunucuya Access-Control-Allow-Origin eklemek de bu sonucu değiştirmez; çünkü CORS, iframe belgesinin DOM yetkisini genişleten bir mekanizma değildir.

İhtiyacınız yalnızca iframe içeriğini göstermekse CORS ayarlamayın. İhtiyacınız üst sayfa ile iframe arasında veri alışverişiyse window.postMessage() kullanın:

Kod:
const frame = document.getElementById("frame");
const expectedOrigin = "https://www.example.com";

frame.addEventListener("load", () => {
  frame.contentWindow.postMessage(
    { type: "theme", value: "dark" },
    expectedOrigin
  );
});

window.addEventListener("message", (event) => {
  if (event.origin !== expectedOrigin) return;
  if (event.source !== frame.contentWindow) return;
  const data = event.data;
  if (!data || typeof data !== "object") return;
  if (data.type !== "theme-received" || data.value !== "dark") return;
  console.log("Iframe yanıtı:", data.value);
});

Önceki DOM kontrolü örneğiyle aynı değişkeni ikinci kez tanımlamayın; mesajlaşma denemesinde o script yerine yukarıdaki üst-sayfa kodunu kullanın. Aşağıdaki kod ise frame.html belgesinde çalışmalıdır:

Kod:
window.addEventListener("message", (event) => {
  if (event.origin !== "https://example.com") return;
  if (event.source !== window.parent) return;
  const data = event.data;
  if (!data || typeof data !== "object") return;
  if (data.type !== "theme" || data.value !== "dark") return;

  document.documentElement.dataset.theme = data.value;
  event.source.postMessage(
    { type: "theme-received", value: data.value },
    "https://example.com"
  );
});

Örnekte yalnız dark değerine izin verilir; bu bir tema değişkenini işaretler, CSS tasarımı içermez. Burada event.origin doğrulanmalı ve bilinen hedef için * kullanılmamalıdır. Mesaj içeriğini de beklenen biçimde kontrol edin. Başarılı sonuç, DOM'u doğrudan okumak değil, iki pencerenin kontrollü mesajlaşmasıdır.

Hangi durumda ne yapmalısınız?​


Aşağıdaki ayrım, yanlış HTTP başlığı eklemenizi önler.
İhtiyaçDoğru yaklaşımCORS yeterli mi?
Uzak sayfayı iframe içinde göstermekIframe URL'sini kullanın; gömülme politikalarını kontrol edinHayır
Üst sayfanın uzak API yanıtını okumasıAPI sunucusunda uygun CORS yanıtı verinEvet, API isteği için
Iframe ile veri alışverişipostMessage ve origin doğrulaması kullanınHayır
Iframe DOM'una doğrudan erişimAynı origin ve uygun sandbox politikası gerekirHayır
Üst sayfanın CSP frame-src politikası da yüklemeyi kısıtlayabilir. Iframe hiç açılmıyorsa sorun CORS yerine X-Frame-Options veya Content Security Policy içindeki frame-ancestors kuralı olabilir. Örneğin X-Frame-Options: DENY tüm iframe gömmelerini engeller; SAMEORIGIN ise yalnızca aynı origin'deki gömmeye izin verir.

Uygulanabilir teşhis adımları​

  1. Üst sayfanın ve iframe src adresinin protokol, alan adı ve portunu karşılaştırın.
  2. Iframe yalnızca gösterilecekse tarayıcı geliştirici araçlarında yanıtın X-Frame-Options ve Content-Security-Policy başlıklarını kontrol edin.
  3. API çağrısı üst sayfanın JavaScript'i tarafından yapılıyorsa API yanıtında izin verilen origin'in bulunup bulunmadığını kontrol edin.
  4. Iframe ile mesajlaşacaksanız iki tarafta da postMessage() kullanın; alıcıda event.origin ve mümkünse event.source doğrulayın.
  5. Iframe DOM'una erişim zorunluysa iframe ve üst sayfayı aynı protokol, host ve port altında sunun. Sandbox gibi ek kısıtlamalar bulunmadığını da kontrol edin. Aksi durumda CORS eklemek yerine mimariyi mesajlaşmaya göre değiştirin.
En sık yapılan hata, konsolda görülen her "CORS" ifadesini iframe sorunu sanmaktır. Iframe'in görünmesi, iframe DOM'unun okunabileceği anlamına gelmez; API yanıtının okunması ise iframe'in gömülebileceği anlamına gelmez. Bu iki yetkiyi ayrı ayrı teşhis edin.

Sık sorulan sorular​


Iframe içindeki sayfa kendi API’sine CORS olmadan istek atabilir mi?​


Normal bir origin altında çalışan iframe kendi origin’indeki API’yi çağırıyorsa CORS izni gerekmez. Üst sayfanın origin’i bu isteğin kaynağı sayılmaz. Ancak sandbox ile opaque origin oluşmuşsa veya başka tarayıcı politikaları varsa davranış farklılaşabilir.

Aynı host üzerindeki sandbox iframe neden DOM erişimi vermeyebilir?​


Sandbox, allow-same-origin olmadan belgeye opaque origin verebilir. Bu durumda URL’ler aynı görünse de DOM erişimi aynı-origin gibi davranmaz. Sırf hatayı gidermek için sandbox izinlerini topluca açmayın; özellikle aynı-origin içerikte script ve same-origin izinlerinin birlikte verilmesi izolasyonu zayıflatabilir.

document.domain kullanarak bu sınırı kaldırabilir miyim?​


document.domain ile origin gevşetme yaklaşımı kullanım dışına alınmaktadır ve modern güvenlik özellikleriyle uyumsuzluk taşır. Yeni uygulamada belirli origin ve kaynak pencereyi doğrulayan mesajlaşma tercih edin; karşı tarafı kontrol edemiyorsanız onun DOM’una erişim yetkisi elde edemezsiniz.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.