Makale Özeti

Bu makalede web dünyasındaki gün geçtikçe yaygınlaşan ve çok popüler uygulama modellerinden biri olan AJAX’ı ele alacağız. XMLHTTPRequest nesnesini inceleyip, bu nesne aracılığıyla bir AJAX uygulamasını nasıl geliştirebileceğimizi göreceğiz.

Makale

Son zamanlarda özellikle web programcılığı ile ilgilenenlerin sıklıkla duyduğu bir terim AJAX. Microsoft’un geçtiğimiz aylarda tam sürümünü çıkardığı ve yeni nesil web sayfalarında sıklıkla kullanacağımız ASP .NET AJAX’a geçiş yapmadan önce AJAX adı verilen uygulama geliştirme yaklaşımını ele almamız, temellerini öğrenmemiz oldukça faydalı olacaktır. Peki AJAX nedir? Bizlere nasıl bir teknoloji ve ne gibi yenilikler sunuyor?

AJAX aslında yeni bir programlama dili ya da programlama aracı değildir. Daha önceden de var olan bazı teknolojileri kullanarak bize nasıl uygulama geliştireceğimizi gösteren yeni bir programlama modelidir. AJAX yani Asenkron JAvascript ve XML, temel olarak JavaScript dilindeki XMLHTTPRequest nesnesini kullanarak web sayfaları üzerinde asenkron bir şekilde veri iletişimini sağlayan programlama modelidir. Yani bir web sayfası yüklendikten sonra, aynı sayfa üzerinde iken arka tarafta sunucu ile iletişime geçmeyi ve veri transferi yapmamıza olanak sağlar. Dilerseniz bu kısmı biraz daha açmak için klasik modelde programlanan bir web sayfasının ve AJAX modelinde programlanan bir web sayfasının nasıl çalıştığını inceleyelim.

Klasik Çalışma Modeli
Klasik model kullanılan bir web sayfasında, istemci web tarayıcısından aldığı isteği sunucuya gönderir(1) ve sunucu bu isteğe göre oluşturduğu içeriği tarayıcıya gönderir(2). Böylece web sayfası istemci tarafından görüntülenir. İstemci aynı sayfa üzerinde yeni bir istekte bulunduğunda ise istek sunucuya tekrar gönderilir(3) ve üretilen içerik tamamen yenilenmiş bir sayfa olarak tarayıcıya gönderilir(4). Bu aslında bugüne kadar gördüğümüz, alışılagelmiş çalışma modelidir. Bir sayfa üzerinden başka bir sayfaya veya içeriğe istekte bulunur ve PostBack işlemi ile sayfa tamamen yenilenir. (Aşağıdaki şekilde klasik çalışma modeli anlatılmıştır.)

AJAX Çalışma Modeli
AJAX mimarisini kullanan bir web sayfasında ise ilk işlemler klasik çalışma modeldeki gibi olur. Yani istemci isteğini sunucuya gönderir(1) ve oluşturulan içerik alınarak tarayıcı üzerinde görüntülenir(2). AJAX’ın getirdiği yenilik işin bundan sonraki kısımlarında karşımıza çıkacaktır. Yüklenen web sayfası üzerinde yeni bir istekte bulunacağımız zaman, istemci tarafında çalışacak olan bir Javascript kodu, arka planda asenkron bir şekilde sunucuya istekte bulunur(3). Sunucudan alınan bilgi yine asenkron bir şekilde getirilir ve gelen yeni içerik ile birlikte sayfamızda ilgili kısımlar güncellenir(4). Bu sayede yeni bir istek durumunda web sayfamız sadece güncelleyeceğimiz verileri alacaktır. Sayfa tamamen PostBack işlemi tabi tutulmayacaktır, kısmi bir PostBack işlemi gerçekleşecektir ve sayfanın tamamen yenilenmesine gerek kalmayacaktır. Bu işlem süresinde sayfa tamamen PostBack edilmeyeceği için farklı bir sayfa beklemesi olmayacak ve aynı sayfa üzerinde kalınacaktır. (Aşağıdaki şekilde AJAX çalışma modeli anlatılmıştır.)

İki çalışma modelini ele alırsak AJAX bizlere klasik çalışma modeline göre daha hızlı ve verimli bir çalışma ortamı sunmaktadır. İstemciye sadece sayfanın güncelleyeceğimiz kısmını getirildiğimiz için daha küçük veri parçalarının transfer edilmesiyle sunucu ve istemci arasındaki trafik azalmakta ve sayfalar daha hızlı bir şekilde yenilenmektir. Yine sayfamızı ziyaret eden kullanıcılar aynı sayfa üzerinde kalacakları için site ile etkileşimleri artacaktır. Bu sayede artık web uygulamaları masaüstü uygulamaların sağladığı hıza ve zenginliğe giderek yaklaşmaktadır.

Dünü, bugünü, yarını…
AJAX’a bu kadar övgünün yeterli olduğunu düşünüyorum. AJAX’ın tarihçesine bakacak olursak aslında birçoğumuzun sandığı gibi AJAX’ın son 1-2 yıl içinde çıkan bir model olmadığını görüyoruz. AJAX’ı uygulamamızı sağlayan XMLHTTPRequest nesnesi ilk olarak Microsoft tarafından Internet Explorer 5.0’ın yapısına eklenmişti. Birçoğumuzun kullanmış olduğu Outlook Web Access aracı AJAX’ı kullanan ilk örneklerden biriydi. Ancak ilk zamanlarda XMLHTTPRequest nesnesinin sadece Internet Explorer’da bulunması ve diğer tarayıcıların bu nesneyi yapısında bulundurmaması nedeniyle AJAX neredeyse hiç kullanılmamıştı. Son zamanlarda ise popüler tüm tarayıcılar artık yapılarında bu nesneyi bulundurmaya başladılar. AJAX’a asıl popülaritesini kazandıran ise Google’ın son birkaç yılda hazırladığı uygulamalar oldu. Google Suggest, Google Earth, Gmail gibi uygulamalar kullanıcıları ve geliştiricilere yepyeni bir web dünyasının haberlerini vermiş oldu. Yine PageFlakes, Microsoft’un Start.com ve VirtualEarth uygulamaları son yıllarda AJAX’ı kullanan ve çok ses getiren sitelerden sadece birkaçı. Şu an kullanılan popüler tarayıcıların neredeyse tamamı (Internet Explorer 5.0+, Firefox 1.0+, Opera 8+, Safari 1.2 ve Netscape 7 sürümleri) XMLHTTPRequest nesnesini bulundurduğu için uygulama geliştiriciler olarak bizlerin bu modeli kullanmasında da herhangi bir sakıncası kalmamıştır. Şu anda giderek yaygınlaşmakta olan AJAX uygulamaları şüphesiz ki giderek artarak gelecekte karşımıza çok daha sık çıkacaktır. Gelişen teknolojilerle paralel olarak internet hızlarının artışını da göze alırsak, gelecekte web uygulamalarının neredeyse masaüstü uygulamalar kadar hızlı ve verimli çalışabileceğini düşünebiliriz.

Nasıl Çalışır?
Peki, AJAX mimarisi nasıl çalışıyor ve bir web sayfasının asenkron bir şekilde sunucuyla iletişime geçmesini nasıl sağlıyor? Yazımızın başında da bahsettiğim gibi AJAX mimarisi temel olarak XMLHTTPRequest nesnesini kullanır. XMLHTTPRequest web tarayıcısı üzerinde bulunan bir bileşendir. JavaScript dilindeki XMLHTTPRequest nesnesi aracılığı ile bu bileşeni kullanabilmekteyiz. Bu nesne sayfa yüklendikten sonra istemci ve sunucunun asenkron şekilde haberleşmesini sağlar. İstemci tarafındaki web tarayıcısı, sunucudan asenkron şekilde veri isteğinde bulunur.(Request) Sunucu tarafında ise alınan isteğe göre bir çıktı üretilir ve veriler yine asenkron şekilde istemcinin web tarayıcısına gönderilir.(Response) Alınan veriler DOM(Document Object Model) ve Javascript sayesinde dinamik bir şekilde sayfaya yüklenmesi sağlanır. Bu esnada sayfada kısmi PostBack işlemi olmakta ve yapılan işlemler sayfanın arka tarafında yapılmaktadır. İşlem süresince tarayıcıdaki sayfa aynen kalmakta ve sadece güncellenen alanlarda değişiklikler olmaktadır.

XMLHTTPRequest Nesnesini İnceleyelim
XMLHTTPRequest nesnesi JavaScript’in içerisinde bulunan bir yapıdır. Bu nesne içerisindeki metotlar, eventhandler ve özellikler sayesinde bir web sayfasının yüklendikten sonra asenkron şekilde sunucu ile haberleşmesini sağlamaktadır. Bu işlemi yaparken kullandığı 2 temel metot vardır. Bunlar open ve send metotlarıdır. Yine asenkron haberleşmenin hangi safhada olduğunu, sunucudan bize bir bilgi dönüp dönmediğini kontrol edebilmemizi sağlayan bir olay ve bir özellik bulunmaktadır. Bunlar da onreadystatechange eventhandler’ı ve readystate özelliği. Gelin isterseniz XMLHTTPRequest nesnesinin üyelerinin kullanımını ve AJAX modelini bir web sayfasına nasıl uygulayabileceğimizi daha iyi anlamak için ilk AJAX örneğimizi hazırlayalım. Öncelikle sayfamızın HTML içeriğini hazırlayalım. HTML sayfamızda <body> içerisine bir tane span elementi ve tipi buton olan bir input elementi ekleyelim.

<span id="lblGuncelle"></span>
<input type="button" value="Güncelle" onclick="AsenkronCagriYap()" />

Buradaki buton yapacağımız asenkron çağrıyı tetikleyecek olan elementimizdir. Bu butona tıkladığımızda az sonra yazacağımız ve adı AsenkronCagriYap() olan JavaScript fonksiyonumuzu çağırıp, çağrı sonucunda dönecek olan bilgileride yine JavaScript içerisinden dinamik bir şekilde id bilgisi lblGuncelle olan span elementimizin içerisine yazdıracağız. JavaScript’teki fonksiyonlarımızı yazmadan önce isterseniz bu bölümün başında anlattığımız XMLHTTPRequest nesnesini nasıl oluşturacağımızı ve bu nesnenin yapısında bulunan üyelerini inceleyelim.

Yeni bir XMLHTTPRequest nesnesi oluşturmak için bilmemiz gereken 3 farklı isimlendirme vardır. Tarayıcının içerisinde bulunan bileşene göre ActiveXObject(“Msxml2.XMLHTTP”), ActiveXObject(“Microsoft.XMLHTTP”) ve XMLHTTPRequest() ile nesne oluşturabiliriz.

IE 6.0+ tarayıcılar için aşağıdaki tanımlama yapılır.
var nesne = new ActiveXObject("Msxml2.XMLHTTP");

IE 5.5 sürümleri için ise aşağıdaki tanımlama yapılır.
var nesne = new ActiveXObject("Microsoft.XMLHTTP");

Mozilla, Opera, Safari gibi tarayıcılar için ise aşağıdaki tanımlama yapılır.
var nesne = new XMLHTTPRequest();

Buradan şöyle bir sonuç çıkıyor. İstemci tarafında farklı tarayıcılar olabileceği için bizim bu ihtimali düşünüp yazacağımız fonksiyonda yukarıdaki tüm ihtimalleri denemeliyiz. Bunun için JavaScript içerisinde try-catch blokları yazarak tarayıcıya göre yeni bir nesne oluşturmalıyız. (Aşağıdaki kod üzerinde çok fazla dırmaya gerek yok. Zira buradaki try-catch yapısı C# .NET ve VB .NET’teki yapıyla hemen hemen aynıdır.)

function NesneOlustur()
{
   var nesne;
   try
   {
      nesne = new ActiveXObject("Msxml2.XMLHTTP"); // IE 6.0+ tarayıcılar için
   }
   catch(e)
   {
      try
      {
         nesne = new ActiveXObject("Microsoft.XMLHTTP"); // IE 5.5 tarayıcıları için
      }
      catch(e)
      {
         try
         {
            nesne = new XMLHTTPRequest(); // Firefox, Opera 8.0+ ve Safari tarayıcıları için
         }
         catch(e)
         {
            alert("Tarayıcınız AJAX'ı desteklemiyor!!!");
            return null;
         }
      }
   }
   return nesne;
}

Yukarıdaki JavaScript fonksiyonu bize istemcinin kullandığı tarayıcıya göre oluşturacağı XMLHTTPRequest nesnesini döndürecektir. Bu nesne üzerinden artık asenkron işlemlere başlayabiliriz. open ve send metotları sunucuya asenkron istekte bulunmamızı sağlamaktadır.

open metodu 3 parametre almaktadır. İlk parametre; isteği hangi metodu kullanarak yapacağımızdır. (GET veya POST) İkinci parametre hangi adrese istekte bulunacağımızdır. (Örneğin sonuc.aspx) Son parametre ise isteğin asenkron bir şekilde gerçekleşip gerçekleşmeyeceğidir. (true değeri asenkron şekilde olacağı anlamına gelir.)

nesne.open(“GET”, “sonuc.aspx”, true);

open nesnesinin 2 ve 5 parametre almış aşırı yüklenmiş halleri de vardır. Yukarıdaki kullanım genel olduğu için bu bize yetecektir.

send metodu ise open ile hazırladığımız isteği sunucuya gönderir. Eğer open ile açacağımız istek POST metodunu kullanıyorsa, send metodu parametre olarak gönderilecek veriyi taşıyabilir. Send metodunu parametresiz veya null parametresi ile de kullanabilmekteyiz.

nesne.send(); veya nesne.send(null);

İsteğimiz sunucuya gönderildi. Artık sunucudan gelecek olan cevabı bekleyip eğer sonuç dönerse bu sonucu HTML kısmında yazmamız kaldı. Bu işlemi yapabilmemiz için yine XMLHTTPRequest içerisinde bulunan onreadystatechange eventhandler’ı ve readystate özelliğini kullanmamız gerekiyor.

onreadystatechange eventhandler’ı sunucuya istekte bulunduktan sonraki durum değişikliklerini yakalar. Burada bahsettiğimiz durumlar ise 5 tanedir ve bu durumları readystate özelliğini kullanarak elde edebiliriz. Bu durumlar;

0 = İstek hazırlanmadı
1 = İstek hazırlandı
2 = İstek gönderildi
3 = İstek değerlendiriliyor ve sonuç bekleniyor
4 = İstek tamamlandı ve sonuç geldi

onreadystatechange olayını atacağımız bir fonksiyon içerisinde readystate değerini kontrol edersek, readystate bize 4 değerini getirdiğinde artık isteğimiz tamamlanmış ve bize bir sonuç getirilmiş demektir.
nesne.onreadystatechange = function
{
   if (nesne.readystate == 4)
   {
      // sonucu HTML’e yazdır
   }
}

Artık HTML kodumuzdaki buton içerisinden çağıracağımız AsenkronCagriYap() fonksiyonunu oluşturabiliriz.
function AsenkronCagriYap()
{
   var yeniNesne = NesneOlustur(); // XMLHTTPRequest nesnemizi oluşturduk

   // Bulunacağımız isteği açıyor ve sunucuya gönderiyoruz. İsteğimiz aynı dizinde bulunan Ogrenciler.htm adresine, GET metodunu kullanarak gerçekleşiyor.
   yeniNesne.open("GET","Ogrenciler.htm",true);
   yeniNesne.send(null);

   // Yeni bir fonksiyon yazmamıza gerek kalmadan onreadystatechange olayını isimsiz bir fonksiyona bağlıyoruz
   yeniNesne.onreadystatechange = function()
   {
      // Eğer readystate 4 değerine sahipse asenkron işlem bitmiş ve veriler getirilmiş demektir
      if(yeniNesne.readystate == 4)
      {
         // Getirilen veriyi HTML kısmındaki lblGuncelle içerisine dinamik bir şekilde yazdırıyoruz
         document.getElementById('lblGuncelle').innerHTML = yeniNesne.responseText;
      }
   }
}

Son olarak belirtmemiz gereken nokta ise document.getElementById('lblGuncelle'). innerHTML şeklinde HTML kısmındaki lblGuncelle span elementine ulaşıyor ve bu elementin içerisine istek sonucunda gelecek olan bilgiyi yazdırıyoruz. yeniNesne.responseText ise Text formatında gelecek olan veriyi almamızı sağşıyor. (responseXML ise DOM’a uygun XML formatında gelen veriyi almamızı sağlar) Sayfamızı çalıştıracak olursak sadece butonu bulunan bir sayfamız olacak. Burada span elementi ile belirttiğimiz boş bir alan daha var. Uygulamamızın doğru çalışıp çalışmadığını görebilmemiz için sayfamızın bulunduğu dizine Ogranciler.htm adında bir dosya oluşturmamız gerekiyor. Bu dosyanın içerisine örnek olması açısından birkaç satırlık yazı ekleyebiliriz. Sayfamızda bulunan butona tıkladığımızda butonun onclick olayı çalışacak ve AsenkronCagriYap() isimli JavaScript fonksiyonumuz çağırılacaktır. Bu fonksiyon asenkron çağrı işlemini gerçekleştirecek ve getirilen bilgiyi lblGuncelle adını verdiğimiz span elementinin içerisine yazacaktır.

Yukarıdaki örneğimizde kullandıklarımız dışında XMLHTTPRequest’in aşağıdaki üyeleri de bulunmaktadır.

Metotlar:
abort() = nesne üzerinden yapılan isteği durdurur.
getAllResponseHeaders() = Gelen cevabın başlık bilgilerini getirir.
getResponseHeader("headerLabel") = Parametre olarak verilen başlık bilgisini getirir.
setRequestHeader("headerLabel", "value") = Gönderilen başlık bilgisine istenilen değeri atar.

Özellikler:
status = Sunucudan dönen cevabın numarasal kodudur. Örneğin 404 kodu “Not Found” yani istekte bulunduğumuz sayfa bulunamadı anlamına gelir. 200 ise “OK” değeri dönderir ve işlemin tamamlandığını belirtir.
statusText = status özelliğinin metin karşılığını verir.

Son kısımda belirtilen metot ve özellikler üzerinde fazla durmamıza gerek olmadığını düşünüyorum. AJAX’ı kullanarak asenkron veri alış-verişini yapabilmek için örneğimizde kullandığımız open ve send metotları, onreadystatechange eventhandler’ı ile readystate özelliği bizim için yeterli olacaktır.

Bu yazımızda AJAX modelini inceleyip web uygulamalarımızda nasıl kullanabileceğmizi ele aldık. AJAX web üzerinde uygulama geliştiriciler için gerçekten köklü ve önemli bir gelişme. ASP .NET geliştiricileri için hazırlanan ve kullanımı giderek yaygınlaşan ASP .NET AJAX aracını kullanmak için AJAX’ı veya JavaScript’i iyi bilmemize gerek olmamasına rağmen temel olarak AJAX modelini nasıl uygulayabileceğimizi öğrenmek bizler için oldukça yararlı olacaktır.

Bir başka makalede görüşmek dileğiyle...

Uğur UMUTLUOĞLU
www.nedirTV.com