AJAX Mustafa Ahmet KARA
Çözümlerden ilki olarak img ile gerçekleştirilmesinden bahsedeceğim ama bu pek tavsiye ettiğim bir çözüm değildir, çünkü büyük verilerde sorunlar yaratır. Bildiğiniz gibi sayfalardaki tüm resimler internette herhangi bir yerden alınabilir ve asenkron olarak arka planda yüklenirler. Dolayısıyla asenkron olması yeterlidir. XMLHttpRequest olmasa bile veriyi gönderebiliriz. Bu işlem için bir örnek vermek için, sunucumuzda tarayıcıdan gelen iki sayıyı toplayıp sonucu cookie olarak gönderen bir kodumuz olsun. img etiketi ile bu işlemi yapmak aşağıdaki gibi olacaktır.
-
function sum(x,y){
-
var img = document.createElement("IMG");
-
img.onload = function(){
-
var result = GetCookie("Toplam");
-
alert(result);
-
}
-
img.src = "http://www.mydomain.com/resim.php?X="+x+"&Y="+y;
-
}
Yukarıdaki örnekte cookie'ler ve img tagları ile istediğimiz bir sayfayı çağırabilir ve sonucu alabiliriz, ama cookie'ler sınırlı olanaklara sahiptir. Bilmek için iyi fakat uygulamak için tercih etmenizi istemediğim bir yöntemdir.
CSS ile çözüm hemen hemen aynıdır fakat sonuçları css tagları içinde gönderirsiniz. Bu çözüm daha büyük dataları işleyebilir ama currentStyle() ve window.getComputedStyle() desteği olan browserlarda çalışır, dolayısıyla tercih edilebilir bir yöntem gene değildir. Ama hedefiniz bu tür browserlar ise çözüm olabilir.
Yukarıdaki bilinmesi gereken ama uygulamada tavsiye etmediğim çözümlerden sonra uygun çözümler olarak gördüğüm script ve iframe çözümlerine gelelim. Bu çözümlerden önce genel özelliklerini karşılaştırırsak:
|
İlk çözümümüz olan SCRIPT etiketi ile Asenkron Javascript işlemlerinin inceleyelim. Sunucumuzda XML çıktıları yerine javascript kodlarını çıktı olarak üreten bir uygulamamız olsun. Bunuda JSON taraftarı olarak JSON çıktısı veren bir uygulamamız olsun olarak değiştirebiliriz. Yapacağımız uygulama gene şehir listesini sunucudan almak olsun. Sunucu çıktımız bir önceki JSON örneğinde olduğu gibi:
-
[ {id:1,name:"Adana"},{id:6,name:"Ankara"},{id:9,name:"Aydın"}]
yerine aşağıdaki şekilde olacaktır.
-
cities = [ {id:1,name:"Adana"},{id:6,name:"Ankara"},{id:9,name:"Aydın"}];
-
onCityLoad(cities);
Bu çıktı ise cities dizisine şehirleri yükler ve combobox'umuzu dolduracak olan koda bu diziyi parametre olarak aktarır. Sayfamızda olması gereken javascript kodu ise aşağıdaki gibidir.
-
<script type='text/javascript'>
-
function loadCities(){
-
var scr = document.createElement("script");
-
scr.type="text/javascript";
-
scr.src="http://www.mydomain.com/cities.php";
-
document.getElementsByTagName("head")[0].appendChild(scr);
-
}
-
-
function onCityLoad(cityList){
-
for(var i = 0;i<cities.length;i++){
-
var option = new Option(json[i].name , json[i].id);
-
document.getElementById("cityCombo").options[i] = option;
-
}
-
}
-
</script>
-
<body onload='loadCities()'>
-
...
Yukarıdaki örnekte XMLHttpRequest kullanmadan asenkron olarak şehir listesinin yapılmasını görebilirsiniz. Script tagı kullanmanın en güzel yanlarından biri direkt olarak javascript kodlarının kullanıcının işlemlerine ve tercihlerine göre üretilmesidir ki bu çoğu programlama dilinde desteklenebilen bir işlem değildir. Bu yöntemin tek dezavantajı ise her bir çağrıda yeni bir script DOM elemanı oluşturursunuz ve sayfanız bellekten atılana kadar bu kodlar kalacaktır. Dolayısıyla uzun süreli sayfa yaşamlarında browserlar sorun yaratabilir.
Son olarak ta Google ve Yahoo gibi AJAX uygulamalarını kendi alan adlarında barındırıp dışarıya sadece api sunan sitelerin tercih ettiği yönteme. Bu yöntemde gizli bir IFRAME oluşturulur ve tüm işlemler bu gizli iframe üzerinden yürütülür. Ayrı bir sayfa olarak tarayıcılar bunları yönettiği için çöp toplama problemleri yoktur. Ayrıca browser'ın izin verdiği sayıda paralel yüklemeler birbirlerini etkilemeden yapılabilir. Az önce script ile yaptığımız örneği IFRAME ile gerçeklediğimizde aslında pek bir farkı olmadığını göreceğiz:
Sunucu çıktımız gene aynı kalacaktır:
-
cities = [ {id:1,name:"Adana"},{id:6,name:"Ankara"},{id:9,name:"Aydın"}];
Ama istemci tarafındaki kodlarımızda biraz değişiklikler olacaktır:
-
<script type='text/javascript'>
-
var callbackFunction = null;
-
var iframe = null;
-
function initIFrame(){
-
iframe = document.createElement("iframe");
-
iframe.onload=onFrameLoaded;
-
iframe.style.display='none';
-
}
-
-
function requestFromIFrame(url,callback){
-
callbackFunction = callback;
-
iframe.src = url;
-
}
-
function onFrameLoaded(){
-
var innerHTML = iframe.contentWindow.document.body;
-
if (callbackFunction ) callbackFunction (result);
-
}
-
-
function loadCities(){
-
requestFromIFrame("http://www.mydomain.com/cities.php",onCityLoad);
-
}
-
-
function onCityLoad(cityList){
-
for(var i = 0;i<cities.length;i++){
-
var option = new Option(json[i].name , json[i].id);
-
document.getElementById("cityCombo").options[i] = option;
-
}
-
}
-
</script>
-
<body onload='initIFrame();loadCities()'>
Yukarıdaki kodumuz sayfa yüklendikten sonra gizli bir iframe yaratır ve bu frame yüklendiğinde çağrılacak fonksiyonu ayarlar. Sonra şehir yükleme isteği yürütülür. Sonuç frame içine yüklendikten sonra yükleme handler devreye girer ve sonucu alır. Bunu Javascript Nesnesine çevirir ve istenilen callback fonksiyonunu çağırır.
Bu yöntemde iframe içeriğini değiştirerek dinamik formlar oluşturarak asenkron dosya yükleme işlemlerinin de yapılması mümkündür.
Bu yazımda AJAX dünyasında bir kısıtlama olarak gördüğüm same-origin policy kuralı hakkında ve aşılması hakkında neler yapılması gerektiğinden bahsettim. Şu anda bu engelden dolayı yeni istekler ve tasarımlar browser üreticilerine istek olarak gitmektedir. Mozilla bu konuda bir gelişmeyi standart haline getirecek ve yakında yayınlanacaktır. Ama şu anda ki gelişmelere baktığımda trend, AJAX componentleri yerine frameworklerin gelmesi ve frameworklerin yerinide AJAX Servislerinin kullanılması. Kendiniz AJAX servisi yaptığınızda XMLHttpRequest kullanımında same-origin policy tamamiyle engel olarak karşınızda olacaktır. Veya kendi AJAX kütüphanelerinizi toplayıp servis haline getirmek istediğinizde aynı problemle karşılaşacaksınız. Umarım ilerleyen yıllarda XMLHttpRequest üzerindeki bu engel, Flash larda olduğu gibi bir ayar dosyasıyla çözülebilir. Bir sonraki yazımda görüşmek üzere şimdilik iyi akşamlar.
Sayfalar: 1 2
Toplamda 3563 kez okunmuş.
Şu an 1 kişi okuyor.
En fazla 6 kişi aynı anda okumuş.
Bugün 13 kez okunmuş.
Etiketler: ajax, asenkron, css, javascript, json, same origin policy
Trackback Yorumları takip et Baskı Önizleme

(12 oy, ortalama 4.08)
# selim | 10 Ekim 2007, 15:58
tam ihtiyacım olan şeyi çok güzel ve ayrıntılı yazmışsınız. birkaç kere bu konuda takılmıştım (iframe in içeriğini almayı bilmiyordum [bilsem de bu aklıma gelmezdi heralde:) ]) çok işime yarıyacak.
şimdi kodumu yazmaya başlıyorum.
teşekkürler.
iyi çalışmalar
# ilhank | 03 Aralık 2007, 10:55
İstifade ettim, faydalı bir yazı olmuş. Tebrikler.
# Eralp | 24 Aralık 2007, 13:21
abicim , ellerine sağlık.
Mükemmel!
bende server side proxy üzerinden hallediyordum ama dediğin gibi request timeout oldukca olasıydi..
JSON+iframe.. en etkili cozum..
# Rnyk Mnyk | 27 Şubat 2008, 08:03
Anlatımınız harika, ayrıca yaklaşık bir hafta kadar aradığım ama ukalalık edip sadece yabancı sitelerde arayıp bulamadığım dop dolu bir içeriği hazırlamışsınız. Teşekkür ve Tebrik ediyorum. Bilginiz ve sabrınız için.