IFrame ile Ana Sayfa Arasında Cross Domain Problemi Nasıl Çözülür?

Selamlar;

Bugün sayfaların içinde kullanılan iframe yani asıl HTML sayfası içerisinde bulunan ve kaynağını, yani içeriğini asıl sayfa dışında başka bir siteden alan çerçeveler hakkında konuşacağız. Aslında istenir ise iframelerin kaynağı aynı site içerisinden de olabilir. Eğer aynı site içinden bir iframe nesnesi, parent yani ana sayfaya üzerinde bir nesneye erişmek ister ise herhangi bir sorun ile karşılaşmaz. Ancak kaynağı asıl sayfa dışında olan bir ifram, bulunduğu ana sayfa üzerinde bir nesneye erişmek ister ise, işte o zaman cross-domain dediğimiz sorunla karşılaşır ve erişilemez. Bu sorunun çözümlerinden biri de Window.postMessage() dır. Iframe’e örnek olarak reklamlar, son listelenen 5 ilan, hava durumu, duyurular gibi çeşitli seneryoları gösterebiliriz. Böylece her bir ana sayfa için tekrardan bir çalışma yapılmasına gerek kalmadan ilgili sayfa, paylaşımlı olarak iframede gösterilir.

Aşağıdaki örnekde sayfalar farklı domainde olduğu için cross domain sıkıntısı yaşanır.

cross2

Image Source: https://www.codeproject.com/KB/HTML/400499/image001.png

Aşağıdaki örnekde sayfalar aynı domainde olduğı için cross domain’e düşülmez.

Image Source: https://www.codeproject.com/KB/HTML/400499/image002.png

Şimdi artık örneğimize geçebiliriz.  Örneğimizde anasayfa ve içinde farklı bir domainde iframe sayfa bulunmaktadır. Ana sayfada yazılan mesajın iframe sayfada, aynı şekilde iframe’de yazılan bir mesajın da ana sayfada gösterilmesi sağlanacaktır. Bir başka konu da Ana sayfada bulunan anahtar resmine tıklanarak, iframe sayfanın arka resminin ve yine aynı şekilde iframe bir sayfada bulunan anahtar resminin tıklanması ile de ana sayfanın arka resminin değiştirilmesi sağlanacaktır.

mesaj

Öncelikle Index.cshtml’i tanımlayalım: Aşağıda ana sayfa ve içinde “borakasmer.com” üzerinde bulunan bir iframe sayfa(Frame.html) bulunmaktadır. Ayrıca yazılan mesaji, iframe sayfaya gönderecek bir “text” element’i ve tıklandığında “send()” function’ını çağran bir button bulunmaktadır. Son olarak iframe’den  gelen mesajın yazılacağı bir “<span>” elementi bulunmaktadır.

Index.cshtml:

Aşağıda button’a basıldığında çağrılan send() function’ı tanımlanmıştır. İlgili iframe’e ait “contentWindow” ile “win.postMessage()” methodu parametre olarak gönderilecek mesaj ve  iframe’in bulunduğu orjinal url girilerek, ilgili mesajın iframe’e gönderilmesi sağlanmıştır. Bir de anahtar resmine tıklanınca “changeBack()” function’ı tetiklenerek iframedeki arka planın değişmesi sağlanır.

post

Index.cshtml(Script):

Aşağıda iframe’e “ChangeBack” şeklinde bir komut ile iframe’in bulunduğu url olan “borakasmer.com”‘a gönderilmekte ve iframe’in arka planının değişmesi sağlanmaktadır.

Index.cshtml(Script):

Aşağıda ana sayfada bulunan, iframe’den gelen komutların dinlendiği listener() function’ı yazılmıştır. Eğer gelen mesaj’ın ‘orgin”i yani url’i “www.borakasmer.com” değil ise hiçbir işlem yapılmaz. Gelen mesaj yani “event.data” “ChangeBack” değil ise ilgili text, “frameMessage” span’ının içine yazılır. Eğer “CallBack” ise arka resim o anki duruma göre ya gösterilir ya da kaldırılır. İlgili listener() function’ı browser destekleniyor ise addEventListener()’ına iligli function eklenir. Parametreler (“adı”,function ismi ve boolen capture kullanılsın mı) dır. Desteklenmiyor ise ilgili listener function’ı attachEvent () ile sayfaya tanımlanır.

Index.cshtml(Script):

Şimdi sıra geldi iframe kodlarına: Aşağıda bir image ve tıklanınca “changeBack()” function’ının çağrılması sağlanmıştır. Ayrıca ana sayfaya mesaj göndermek amacı ile bir input alan ve yanına da tıklanınca “SendParent()” function’ını çağıran bir “Gönder” button’u konulmuştur. Son olarak ana sayfadan gelen mesajların gösterildiği “Message” id’li bir “span” bulunmaktadır.

frm2

Frame.cshtml:

Aşağıda Iframe sayfasında(Frame.cshtml) yazılan scriptler görülmektedir. Öncelikle listener() function’ı ile Ana sayfadan gelen mesajlar dinlenir. Yeni bir mesaj geldiği zaman, mesajın geldiği url’in yani origin’in (localhost:38733) olup olmadığna göre işleme devam edilir yada kesilir. Eğer koşul sağlanır ise ve gelen mesaj “ChangeBack” değil ise ilgili mesaj “Message” span’ının içine yazılır. Eğer “ChangeBack” ise bu durum ana sayfadan kırmızı düğmeye basıldığı anlamına gelir. Bu koşulda iframe sayfanın arka resmi değiştirilir. Gene aynı şekilde “changeBack()” function’ı ile ana sayfaya ilgili komut ve gideceği url “localhost:38733” şeklinde parametre olarak geçilerek arka resmin değişmesi sağlanır. “SendParent()” function’ı ile “sendMessage” input alanına girilen text ana sayfaya mesaj ve url parametereleri ile birlikte gönderilir. İlgili listener() function’ı, browser destekliyor ise addEventListener() methodu ile sisteme eklenir. Parametreler (“adı”,function ismi ve boolen capture kullanılsın mı) dır. Eğer desteklemiyor ise ilgili listener function’ı attachEvent () ile sayfaya tanımlanır.

Frame.cshtml(Script):

Index.cshtml(Full):

Frame.cshtml(Full):

Böylece yukarıdaki örnekde de görüldüğü gibi iki farklı domaindeki sayfaları “postMessage” ile konuşturmayı başardık. Iframe sayfadan bir üst sayfadaki bir nesneye ulaşmamız gerekse idi; örneğin iframe içinden, bulunduğu anasayfadaki “id” değerini yani Iframe’in ana sayfadaki “id” değerini almak isteseydik bu yöntem ile direk erişemezdik. Bunu nasıl alabileceğimiz size ödev olsun. Cevabı yorumlarda bekliyorum.

Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.

Source: https://www.codeproject.com/Articles/400499/How-To-Safeguard-Your-Site-With-HTML-Sandbox

Örnek Sayfa(İptal) : http://iframecrossdomain.azurewebsites.net/

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

10 Cevaplar

  1. çağrı dedi ki:

    abi bu borsoft varmı yoksa ne zaman kurucaksın :)

  2. Cihan dedi ki:

    Merhaba,

    Aşağıdaki gibi bir örnek içerisinde bulunan web sitenin kaynak kodunu nasıl alabiliriz yardımcı olabilir misiniz.

    Teşekkürler.

    • borsoft dedi ki:

      Selam,
      ifram sayfanın Url’ini alıp ayrı bir browserda açıp kolaylıkla kaynağı görüntüleyebilirsin. Ayrıca Browser Devtools’dan / Source sekmesinden ilgili script dosyalarının kodlarına erişebilirsin.
      İyi çalışmalar.

      • deniz dedi ki:

        Merhaba,

        Benim istediğim örnek olarak şöyle; test.html sayfasının içerisinde birtane iframe var bunun içerisinde açılan site “borakasmer.com” iframe içerisinde açık olan web adresinin kaynak kodlarına javascript ile browser domunda(test.html içerisinde) erişmek.

        İyi çalışmalar.

        • borsoft dedi ki:

          Selam deniz,
          İlgili iframe sayfayı Chrome bir browser’dan sağ click yapıp, kaynağı göster dersen ilgili iframe sayfanın da kaynak kodlarını görebilirsin.

          İyi çalışmalar.

  3. Erdogan dedi ki:

    Merhaba, makale icin tesekkurler. Hedef site (iframe src) yine bize ait oldugu icin bahsettiginiz sey yapilabiliyor. Peki, iframe icerisinde oradan oraya ziyaret eden bu kullandirma amaci gudulse nasil mumkun olurdu? Iframe’ e js inject yolunu denedim fakat yine cross-origin engeline takildim. Proxy uzerinden request atip HtmlDocument e bastim ve sayfaya yukledim, tum src’ leri proxy’ e gore yonlendirdim oldu ama cok sorun cikiyor. En optimal cozumu ariyorum, fikriniz var mi hocam?

    Tesekkurler.

    • borsoft dedi ki:

      Selamlar, sizin kontrolünüz dışında bir sayfa, yani hiç bilmediğiniz bir sayfada IFrame parent’a erişemez. 2 sayfada da sizin scriptiniz olması gerekir. Hem Iframede hem de, konulduğu ana sayfada.

  4. mehmet salih bindak dedi ki:

    makale için teşekkür ederim. anladığım kadarıyla kullanacağım fonksiyonu hem iframe hem de dış sayfada kendim yerleştiriyorum.
    Ben iframe’deki sayfanın cookie bilgisi alınabilir mi diye araştırıyorum aslında.

    Anladığım kadarıyla mümkün gözükmüyor.

  5. halil dedi ki:

    selamlar şu sorun için öneriniz çözümünüz var mı hocam ? https://stackoverflow.com/questions/65805882/safari-iframe-reload-bug-opening-a-site-within-the-site

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.