Selamlar,
XmlHttpRequest; Microsoft'un dünyaya (bayağı bir zaman oldu ama) dinamik internet sayfalarını armağan etme yoludur. Bu özellikten vaz geçmek istediğiniz anda, statik sayfalara geri dönmüş oluyorsunuz. Asenkron ya da senkron olarak yüklenmiş olan sayfada dinamik içerik hazırlamaya yarar. Ajax dediğimiz dünya zaten bu komut üstüne kurulmuştur desek yerinde bir tespit olur. Eğer javascript ile istemci (client) tarafında sunucudan (server) dinamik olarak içerik almak ve işleyip kullanıcıya sunmak istiyorsak bukomutu kullanmak isteriz.
Bildiğimiz ve hergün acı olarak tecrübe ettiğimiz gibi internet için çok sayıda standart var ama hiç standart yok! Ne demek bu? Biri birşey yaratıyor, başkaları alternatiflerini üretiyor sonra içlerinden bir ya da birkaçı tutuyor ve internet standardı olma yolna giriyor, sonra üretenler aralarında konuşup bunu standart haline getiriyorlar ama bu seferde hepsinin yoğurt yeme stili farklı oluyor. Çok uzattım ama ne yazık ki bu komut için de bu olay geçerli. Eğer XmlHttpRequest kullanmak istiyorsanız, Javascript ile bu komutu bir nesne gibi yaratmanız gerekiyor ve her tarayıcıda (browser) bu işlem farklı oluyor. Microsoft bunu daha önceden ActiveX nesnesi olarak tanıtmıştı mesela...
Aşağıdaki kod ile XmlHttpRequest nesnenizi tanımlayabilirsiniz:
<script type="text/javascript" language="javascript">
var xmlhttp = false;
function getHttpRequestObj()
{
try
{
//bir deneyelim bakalim
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
//simdi guncel IE implementasyonu deneyelim
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
xmlhttp = false;
}
}
if(!xmlhttp && typeof XmlHttpRequest!= 'undefined')
{
//Eh, artik mozilla tabanli bir tarayici kullaniyoruzdur
//o zaman ona gore bir nesne tanimlayalim
xmlhttp = new XmlHttpRequest();
}
}
</script>
Şimdi bu script ile sayfa içerisinde kullanabileceğimiz xmlhttp adında bir XmlHttpRequest nesnemiz oldu. Artık bununla istediğimiz gibi text, xml ya da json tabanlı içerikler alabilir ve işleyebiliriz. İşin doğrusu benim favorim JSon, çünkü xml'den de text'den de çok daha verimli ve performanslı. Üstüne üstlük geri dönen değer direk olarak javascript nesnesi olarak kullanılabiliyor yani bir daha işlemeye gerek kalmıyor.
Bir örnek vereyim. Bir sayfanızda, sayfanızla aynı klasörde bulunan bir txt dosyasından içerik almak ve göstermek istiyorsunuz diyelim:
getHttpRequestObj();
if(xmlhttp)
{
xmlhttp.open("GET", "Deneme.txt", true);
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readystate == 4)
{
alert(xmlhttp.responseText);
}
}
xmlhttp.send(null);
}
Yukarıdaki örnekte, sayfamızla aynı klasörde bulunan Deneme.txt adlı dosyamızı çağırdık ve içeriğini mesaj kutusuyla gösterdik. Bunu yaparken bazı şeyler yaptık,onları da açıklayayım.
Öncelikle xmlhttp.onreadystate - function()... diye bir komut yazdık. Bu resmen bir event'i handle etmekti. Yani tanımlamış olduğumuz bir başka fonksiyon varsa onu da gösterebilirdik bu event için. Ayrıca xmlhttp.readystate diye bir değişkenin değerinin 4 olup olmadığına baktık, bu da xmlhttp nesnesinin durumunu kontrol etmek içindi. Tahmin ettiğiniz üzere 4 değeri 'tamamlandı' anlamına geliyor.
Diğer durumlarda şöyle:
0 - Henüz hazırlanmadı (Uninitialized)
1 - Yükleniyor (Loading)
2 - Yüklendi (Loaded)
3 - Etkileşimli (Interactive)
4 - Tamamlandı (Complete)
Evet, şu anda bu kod çalışır durumda. Ama henüz gerçek dünyada kullanılabilecek düzeyde değil. Neden mi? Mesela bazen bazı kaynaklara ulaşmakta problemler yaşanır, bu durum için herhangi bir önlem almadık bu kodda. Bunu da ekleyelim şimdi:
if(xmlhttp)
{
xmlhttp.open("GET", "Deneme.txt", true);
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readystate == 4)
{
if(xmlhttp.status == 200)
{
alert(xmlhttp.responseText);
}
else
{
alert("Aman Allahim! Problem Oldu...");
}
}
}
xmlhttp.send(null);
}
Evet, burada xmlhttp.status == 200 diye bir kontrol eklemiş olduk, bu da tahmin ettiğiniz gibi http için status değeridir. Misal, eğer dosya bulunamamış olsaydı 404 değerini alacaktık, ya da sunucu hatası olsaydı 500 alacaktık. Bunlar için de kontroller ekleyebilirsiniz.
Esasen kendi sitenizde barındırdığınız ve kontrol etmiş olduğunuz şeylere erişim sorunu yaşamazsınız ancak dışarıdaki bir kaynağa erişmeye çalışırken bu tür durumlar için dikkat etmek gerekir (Bence içeride de olsa dikkat etmekte yarar var, çünkü bazen bir içeriği değiştirirken ya da bir şeyin yerini değiştirirken nerelerde kullanıldığını unutabiliriz).
Tabi bu örnekte kullandığımız gibi sadece text dosyaları için kullanılmıyor bu komut, yukarıda da belirttiğim gibi xml gibi içeriklerde kullanılabilir ki sadece dosya olarak da kullanılmıyor, misal bir web servis de kullanabilirdik.
Düşünelim. Bir web servisimiz olsa, içinde veritabanımızdan bir liste çeksek ve xml olarak fonksiyondan geri döndürsek, bunu da xmlhttp nesnemizle belirli zaman aralıklarıyla çekip çekip kontrol etsek? Evet, bu yapılan birşey ve kullanım alanlarından biri. Bu gibi durumlarda en yukarılarda da yazdığım gibi xml yerine JSon tavsiye ediyorum, çünkü xmlden çok daha az yer tutuyor bu da veriyi daha çabuk elde etmek, kullanılan bant genişliğini düşürmek gibi anlamlara geldiği gibi ayrıca bir de JSon tipini XML gibi işlemek zorunda kalmadan eval komutuyla direk olarak bir javascript değişkenine atayıp kullanabiliyoruz. Evet işte bu gerçekten süper bir durum. Örnek vereyim.
Bir dosyamız olsun yine (Örnek kolay olsun diye böyle yapıyorum), adı da Deneme2.txt olsun. İçine de aşağıdaki gibi birşey yazalım.
{ "Results": {
"toplam_kitap" : "2",
"kitap" : [
{
"Yayinevi" : "Ayrinti",
"Tur" : "Yeralti Edebiyati",
"Fiyat" : "10"
},
{
"Yayinevi" : "Can",
"Tur" : "Dunya Klasigi",
"Fiyat" : "7"
}
]
}
}
Bu dosyayı kaydedelim. Ve aşağıdaki kodu html kodumuza yazalım:
<script type="text/javascript" language="javascript">
var xmlhttp = false;
function getHttpRequestObj()
{
try
{
//bir deneyelim bakalim
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
//simdi guncel IE implementasyonu deneyelim
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
xmlhttp = false;
}
}
if(!xmlhttp && typeof XmlHttpRequest!= 'undefined')
{
//Eh, artik mozilla tabanli bir tarayici kullaniyoruzdur
//o zaman ona gore bir nesne tanimlayalim
xmlhttp = new XmlHttpRequest();
}
}
getHttpRequestObj();
function CallBack()
{
if(xmlhttp)
{
xmlhttp.open("GET", "Deneme2.txt", true);
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readystate == 4)
{
if(cmlhttp.status == 200)
{
eval("var objResults = " + xmlhttp.responseText);
var displayText;
for(var i=0; i < objResults.Results.kitap.length; i++)
{
displayText += objResults.Results.kitap[i].Yayinevi + " " +
objResults.Results.kitap[i].Tur + ", " +
objResults.Results.kitap[i].Fiyat + "TL<br/>";
}
alert(displayText);
}
else
{
alert("Aman Allahim! Problem Oldu...");
}
}
}
xmlhttp.send(null);
}
}
CallBack();
</script>
Evet, işte bu kadar basit. Tabii biz burada Deneme2.txt diye bir dosya yarattık ve elimizle doldurduk ama dediğim gibi bu örneğin maksadı XmlHttpRequest'i göstermekti bu sebeple diğer detaylarla boğmak istemedim yazıyı. Normalde bir web servis hazırlamak ve geri dönecek değeri JSon tipine parse etmek gerekecekti. Bunlar için de aşağıda kısayollar vereceğim.
Bütün bunların yanı sıra birkaç detay daha vermek istiyorum. Mesela hazırladığımız Deneme2.txt dosyasının formatı JSon ama bu JSon da '{' ya da '[' ne anlama geliyor?
Object(s): '{}' ile başlayıp bitiyorlar.
Object Member(s): Bunlar name - value eşlemesi olarak yer alıyorlar. Name ve value arasında ':'kullanılıyor ve diğer üyeler arasında ise ',' kullanılıyor
Array(s): Bunlar string, number, object, array veya literal value (true, false) ya da null olabiliyorlar.
String(s): Bildiğimiz string.
Bunun yanı sıra bir de XmlHttpRequest nesnesinin metodları (methods) ve özelliklerinden (properties) de bahsetmek istiyorum.
Methods:
- abort()
İsteği iptal eder.
- getAllResponseHeaders()
Bütün Http Header değerlerini getirir.
- getResponseHeader()
Belirtilen Http Header değerini getirir.
- open()
İstek nesnesini belirtilen metod, url ve güvenlik bilgileriyle yapılandırır. (Yukarıda hep tek parametreli olarak kullandık ancak ilk parametrede açılacak kaynağı belirttikten sonra kullanıcı adı ve şifre de belirtebilir ve güvenlik için giriş yapabilirdik).
- send()
Sunucuya bi istek gönderip cevap alır.
- setRequestHeader()
Bir Http header'ın değerini değiştirir.
Properties
- onReadyStateChange (Okuma / Yazma)
ReadyState değiştiğinde tetiklenecek olan event için kullanılacak olan fonksiyonu değiştirir.
- readyState (Okuma)
Nesnenin mevcut durumunu alır.
- responseBody (Okuma)
Http response için kullanılabilecek özelliklerden biri.
- responseStream (Okuma)
Http response için kullanılabilecek özelliklerden biri.
- responseText (Okuma)
Response body, string formatında.
- responseXML (Okuma)
Response body, xml formatında.
- status (Okuma)
İstek için geri dönen durum değeri (200 = OK, 404 = Yok, 500 = server hatası, ...)
- statusText (Okuma)
İstek için geri dönen durumun text'ini döndürür.
Şimdilik bu kadar. Bu konuda daha çok yazı yazmaya ve örnekler vermeye çalışacağım.
Bu konularda bakımlası gereken bazı siteler:
http://www.json.org
http://www.json.com
http://blogs.techrepublic.com.com/security/?p=426