You are on page 1of 129

Ajax Üzerine Ayrıntılı Bir İnceleme, Bölüm 1:

Ajax’a Giriş
Web sitesi oluşturma konusunda verimli bir yaklaşım olan Ajax’ı ve nasıl çalıştığını anlamak

Düzey: Giriş

Brett McLaughlin (brett@oreilly.com), Yazar ve Editör, O'Reilly ve Ortakları

06 Aralık 2005

HTML, JavaScript™ teknolojisi, DHTML ve DOM’dan oluşan Ajax, eski ve hantal Web
arabirimlerini etkileşimli Ajax uygulamalarına dönüştürmenizi sağlayan önemli bir
yaklaşımdır. Ajax uzmanı olan yazar, bu teknolojilerin birlikte çalışarak Web geliştirmesinde
çok verimli sonuçlar elde edilmesinin kolay bir gerçekliğe nasıl dönüştürüldüğünü genel
bilgilerden başlayıp daha ayrıntılı bilgelere geçerek göstermektedir. Ayrıca, XMLHttpRequest
nesnesi gibi Ajax’ın temel kavramlarına da ışık tutmaktadır.

Beş yıl önce, XML bilginiz yoksa, kimsenin konuşmadığı çirkin ördek yavrusu gibi
görülürdünüz. On sekiz ay önce, Ruby gündeme geldi ve Ruby konusunda bilgisi olmayan
programcıların, iş arkadaşlarının ayaküstü sohbetlerine katılması bile zordu. Bugün, en son
teknoloji furyasına kapılmak istiyorsanız, işe Ajax ile başlamanız gerekiyor.

Bununla birlikte, Ajax yalnızca gelip geçici bir akım değildir; web sitesi geliştirmek
konusunda güçlü bir yaklaşımdır ve yeni bir dili öğrenmek kadar zor değildir.

Ajax’ı derinlemesine incelemeye başlamadan önce, Ajax’ın neler yaptığını anlamak için
birkaç dakikamızı ayıralım. Bugün bir uygulama yazarken, iki temel seçim olanağınız vardır:

• Masaüstü uygulamaları
• Web uygulamaları

Her iki tip uygulama da bilinen uygulamalar; masaüstü uygulamaları genellikle bir CD’de
gelir (ya da bazen bir Web sitesinden yüklenir) ve bilgisayarınıza tam olarak kurulur.
Güncellemeleri yüklemek için Internet’i kullanabilirler, ancak bu uygulamaları çalıştıran kod
masaüstünüzde yer alır. Web uygulamalarıysa, sizin de bildiğiniz gibi, başka bir yerdeki bir
Web sunucusu üzerinde çalışır ve uygulamaya Web tarayıcınızla erişirsiniz.

Aslında, bu uygulamaların kodlarının nerede çalıştığından daha önemli olan, uygulamaların


nasıl işlediği ve bunlarla nasıl etkileşim kurduğunuzdur. Masaüstü uygulamaları genellikle
oldukça hızlıdır (çünkü bilgisayarınızda çalışırlar; Internet bağlantısı beklemezsiniz), büyük
kullanıcı arabirimleri (genellikle işletim sisteminizle etkileşim halinde olurlar) içerirler ve
inanılmaz derecede dinamiktirler. Tıklatma, işaretleme, yazma, menüleri ve alt menüleri
çıkarma ve gezinme yoluyla neredeyse hiç beklemeden çalışabilirsiniz.

Diğer yandan, Web uygulamaları genellikle saniyesi saniyesine günceldir ve asla


masaüstünüze alamayacağınız hizmetler sağlarlar (Amazon.com ve eBay’i düşünün). Ancak,

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 1/129


Web’in gücünün yanında beklemek de vardır; sunucunun yanıt vermesini, ekranın
yenilenmesini, isteğin geri gelmesini ve yeni sayfa yaratmasını beklersiniz.

Tabii bu anlatım biraz fazla basitleştirme oldu ancak ana fikri almış olduğunuzu
düşünüyorum. Sizin de tahmin edebileceğiniz gibi, Ajax bir masaüstü uygulamasının
işlevselliği ve etkileşimi ile her zaman güncellenen bir Web uygulaması arasındaki mesafeyi
kapatmaya çalışır. Bir masaüstü uygulamasında bulabileceğinize benzer dinamik kullanıcı
arabirimleri ve hoş denetimler kullanabilirsiniz, ama bunlar size Web uygulamasında sunulur.

Bu durumda daha ne bekliyorsunuz? Ajax’a göz atmaya başlayın; eski ve hantal Web
arabirimlerinizi hızlı yanıt veren Ajax uygulamalarına dönüştürün.

Eski teknoloji, yeni numaralar


Ajax birçok teknolojiyi içerir, temel olanları geçerek bazı farklı teknolojileri daha ayrıntılı
olarak incelemeniz gerekir (bu nedenle, bu dizideki ilk birkaç yazıda bu teknolojilerden her
birini ayıracağım). Bu teknolojilerden birçoğu hakkında zaten yeterli bilginiz olduğunu
sanıyorum (daha da güzeli, bu ayrı teknolojilerin birçoğunu öğrenmek kolaydır); en azından
işimiz Java ya da Ruby gibi tüm bir programlama dilini öğrenmek kadar zor olmayacak.

Aşağıda Ajax uygulamalarında bulunan temel teknolojiler verilmiştir:

• HTML, Web formları oluşturmak ve uygulamanızın geri kalanında kullanılacak


alanları belirlemek için kullanılır.
• JavaScript kodu, Ajax uygulamalarını çalıştıran esas koddur ve sunucu
uygulamalarıyla iletişimi kolaylaştırır.
• DHTML ya da Dynamic HTML formlarınızı dinamik olarak güncellemenizi sağlar.
div, span, ve diğer dinamik HTML öğelerini kullanarak HTML öğelerinizi
biçimlendirirsiniz.
• DOM, Document Object Model (Belge Nesne Modeli), hem HTML yapısı, hem de
(bazı durumalarda) sunucudan dönen XML yapısıyla çalışmak için kullanılır
(JavaScript kodu aracılığıyla).

Şimdi bunları ayıralım ve her birinin neler yaptığına daha yakından bakalım. Bu
teknolojilerden her birini daha sonraki yazılarımda derinlemesine ele alacağım; şu anda bu
bileşenleri ve teknolojileri tanımaya odaklanalım. Bu kod hakkında ne kadar çok şey
bilirseniz, bu teknolojilerle ilgili genel geçer bilgilerden her birini ustalıkla kullanmaya (ve
Web uygulaması geliştirme yeteneklerinizi zenginleştirmeye) geçişiniz daha kolay olacaktır.

XMLHttpRequest nesnesi
Anlamak istediğiniz ilk nesne büyük olasılıkla sizin için en yeni olan XMLHttpRequest adlı
nesnedir. Bu bir JavaScript nesnesidir ve Liste 1’de gösterildiği kadar basit bir şekilde
yaratılabilir.

Liste 1. Yeni bir XMLHttpRequest nesnesi yaratma

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 2/129


<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>

Bir sonraki yazımda, bu nesneyi daha ayrıntılı ele alacağım, ama şimdilik bu nesnenin tüm
sunucu iletişiminizi yürüten nesne olduğunu anlamanız önemli. Diğer konuya geçmeden önce,
sunucuyla iletişim kuranın XMLHttpRequest nesnesi yoluyla JavaScript teknolojisi olduğunu
düşünün. Bu normal uygulama akışı değildir ve Ajax’ın sihiri büyük ölçüde buradan gelir.

Normal bir Web uygulamasında, kullanıcılar form alanlarını doldurur ve bir Submit (Gönder)
düğmesini tıklatır. Sonra, formun tamamı sunucuya gönderilir, sunucu bir komut dosyasını
işlemeye geçer (genellikle PHP ya da Java ya da belki bir CGI işlemi ya da benzeri) ve komut
dosyası tamamlandığında, sunucu geriye yepyeni bir sayfa gönderir. Bu sayfa, bazı verilerle
doldurulmuş yeni bir form içeren HTML olabilir, bir onay olabilir ya da belki, özgün forma
girilen verilere göre seçilen bazı seçenekleri içeren bir sayfa olabilir. Tabii ki, sunucudaki
komut dosyası ya da program işlem yaparken ve yeni bir form döndürürken, kullanıcıların
beklemesi gerekir. Bu sırada ekran boş kalır ve sunucudan veri geri geldikçe yeniden dolar.
İşte düşük etkileşimin ortaya çıktığı yer burasıdır; kullanıcılar anında geribildirim almaz ve
kesinlikle bir masaüstü uygulamasında çalışıyorlarmış gibi hissetmezler.

Ajax temelde JavaScript teknolojisini ve XMLHttpRequest nesnesini Web formunuz ile


sunucu arasına koyar. Kullanıcı formları doldurduğunda, veriler doğrudan sunucuya değil
birtakım JavaScript koduna gönderilir. Sunucunun yerine, JavaScript kodu form verilerini alır
ve sunucuya bir istek gönderir. Bu sırada, kullanıcı ekranındaki form yanıp sönmez, ekrandan
gitmez ya da ekranda donup kalmaz. Diğer bir deyişle, JavaScript kodu isteği arka planda
gönderir; hatta kullanıcı istek yapıldığını bile fark etmez. Daha da güzeli, istek eşzamanlı
olmadan gönderilir; yani, JavaScript kodunuz (ve kullanıcı) sunucunun yanıt vermesini
beklemez. Bu nedenle, veri girmeyi, gezinmeyi ya da uygulamayı kullanmayı sürdürebilirler.

Sonra, sunucu, verileri bunlarla ne yapılacağına karar verecek olan JavaScript kodunuza geri
gönderir (hala Web formunun yerine çalışır). JavaScript kodu form alanlarını hızlı bir şekilde
güncelleyebilir, bu şekilde uygulamanızın hızlı olduğu izlenimini verir (kullanıcılar formları
gönderilmeden ya da yenilenmeden yeni verileri alırlar). Hatta JavaScript kodu, kullanıcının
müdahalesi olmadan, verileri alabilir, bazı hesaplamalar yapabilir ve başka bir istek
gönderebilir! Bu, XMLHttpRequest nesnesinin gücüdür. Kullanıcı farkında bile olmadan bu
nesne, istediği bir sunucuyla iletişim kurabilir. Sonuç, arkasında yatan Internet teknolojisinin
gücüyle, bir masaüstü uygulaması gibi dinamik, hızlı yanıt veren, yüksek düzeyde etkileşimli
bir deneyimdir.

JavaScript ekleme
XMLHttpRequest nesnesini nasıl kullanacağınızı öğrendikten sonra, JavaScript kodunuzun
geri kalanı oldukça sıradan gelir. Aslında, JavaScript kodunu yalnızca birkaç temel görev için
kullanırsınız:

• Form verilerini alma: JavaScript kodu HTML formunuzdan veri almayı ve bunları
sunucuya göndermeyi kolaylaştırır.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 3/129


• Formdaki değerleri değiştirme: Alan değerlerini belirlemek, görüntüleri hızlı bir
şekilde değiştirmek gibi form güncelleme işlemlerini gerçekleştirmek de basittir.
• HTML ve XML ayrıştırma: JavaScript kodunu DOM’u işlemek (sonraki bölüme
bakın) ve HTML formunuzun ve sunucunun döndürdüğü XML verilerinin yapısıyla
çalışmak için kullanırsınız.

İlk iki madde için, Liste 2’de gösterildği gibi getElementById() yöntemini öğrenmek
isteyebilirsiniz.

Liste 2. JavaScript koduyla alan değerlerini alma ve belirleme

// Get the value of the "phone" field and stuff it in a variable called
phone
var phone = document.getElementById("phone").value;

// Set some values on a form using an array called response


document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];

Burada çok dikkate değer birşey yok ve bu bizim için iyi. Sanırım bu konunun çok karmaşık
bir tarafı olmadığını fark etmeye başladınız. XMLHttpRequest nesnesini iyice öğrendikten
sonra, Ajax uygulamanızın geri kalanının büyük bir bölümü, Liste 2’de gösterildiği gibi biraz
akıllı HTML ile karışık basit JavaScript kodu olacaktır. Sonra, zaman zaman biraz DOM işi
olur. Bu yüzden şimdi DOM’a geçelim.

DOM ile bitirme


Son olarak aynı derecede önemli DOM’u, yani Belge Nesne Modelini (Document Object
Model) ele alacağız. Bazılarınız için DOM konusunun açılması biraz ürkütücü olabilir, çünkü
DOM, HTML tasarımcıları tarafından çok sık kullanılmaz ve JavaScript kodlayıcıları için,
özellikle de gerçekten bir takım üst uç programlama işleriyle uğraşmıyorlarsa biraz değişiktir.
DOM’un en fazla kullanıldığı alan yoğun emek gerektiren Java ve C/C++ programlarıdır; işte
tam da bu nedenle DOM’u öğrenmenin zor olduğuna inanılır.

Neyse ki, DOM’u JavaScript teknolojisinde kullanmak kolaydır. Bu noktada, normal olarak
size DOM’un nasıl kullanılacağını gösterirdim ya da en azından birkaç kod örneği verirdim,
ancak bu bile yanlış yönlendirici olabilirdi. Görüyorsunuz, DOM konusunu fazla
kurcalamadan Ajax konusunda yeterince bilgi sahibi olabilirsiniz, size de bu yolu
göstereceğim. DOM konusunu daha sonraki bir yazımda ele alacağım, şimdilik, yalnızca
DOM’un işin içinde olduğunu bilmeniz yeterli. XML’i JavaScript kodunuz ve sunucu
arasında geri gönderip yeniden aldığınızda ve HTML kodunu gerçekten değiştirdiğinizde,
DOM konusuna yeniden gireceksiniz. Şimdilik, DOM olmadan devam ederek Ajax
konusunda yararlı şeyler öğrenmek kolay olacağından DOM’u dışarıda bırakalım.

İstek nesnesi alma


Konuyla ilgili genel bir bakış sahibi olduğunuz için şimdi bazı özel konulara geçebilirsiniz.
Ajax uygulamalarının merkezinde XMLHttpRequest olduğundan ve bu kavram büyük

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 4/129


olasılıkla birçoğunuz için yeni olduğundan, konuya buradan başlayacağım. Liste 1’de
gördüğünüz gibi, bu nesneyi yaratmak ve kullanmak oldukça kolay, değil mi? Bir dakika
bekleyin.

Birkaç sene öncesinde yaşanan can sıkıcı tarayıcı savaşlarını ve tarayıcıların hiçbirinin aynı
şekilde çalışmadığını hatırlıyor musunuz? İster inanın, ister inanmayın ama bu savaşlar daha
küçük ölçekli de olsa hala sürüyor. Ve sürpriz: XMLHttpRequest bu kavganın kurbanlarından
biridir. Bu nedenle, bir XMLHttpRequest nesnesini çalıştırmak için birkaç farklı şey yapmanız
gerekiyor. Size bu işlemleri adım adım göstereceğim.

Microsoft tarayıcılarıyla çalışma


Microsoft'un tarayıcısı olan Internet Explorer, XML işlemlerinde MSXML ayrıştırıcısını
kullanır (MSXML hakkında daha fazla bilgi için Kaynaklar bölümüne bakabilirsiniz). Bu
nedenle, Internet Explorer üzerinde çalışacak Ajax uygulamaları yazarken, nesneyi belirli bir
yolu izleyerek yaratmanız gerekir.

Ancak, bu iş bu denli kolay değildir. Internet Explorer’da kurulu olan JavaScript


teknolojisinin sürümüne bağlı olarak, MSXML’in etrafta dolaşan iki farklı sürümü vardır; bu
nedenle, yazacağınız kodun her iki durum için de kullanışlı olması gerekir. Microsoft
tarayıcılarında XMLHttpRequest nesnesi yaratırken kullanmanız gereken kodlar için Liste 3’e
bakın.

Liste 3. Microsoft tarayıcılarında XMLHttpRequest nesnesi yaratma

var xmlHttp = false;


try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}

Tüm bunların henüz tam olarak birşey ifade etmemesi normaldir. Bu dizi bitmeden önce
JavaScript programlama, hata yönetimi, koşullu derleme ve başka birçok konu hakkında
derinlemesine bilgi sahibi olmuş olacaksınız. Şimdilik, aşağıdaki iki temel satırı öğrenmeniz
yeterlidir:

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

ve

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.

Birkaç sözcükle toparlayacak olursak, bu kod nesneyi MSXML sürümlerinden birini


kullanarak yaratmaya çalışır; nesneyi bu şekilde yaratamazsa, diğer sürümü kullanarak

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 5/129


yaratır. Güzel değil mi? Bu yöntemlerden hiçbiri işe yaramazsa, xmlHttp değişkeni false
(yanlış) olarak belirlenerek kodunuza birşeyin çalışmadığı bildirilir. Bu durumla
karşılaşırsanız, büyük olasılıkla Microsoft dışı bir tarayıcınız vardır ve işi yapmak için farklı
bir kod kullanmanız gerekir.

Mozilla ve Microsoft dışı tarayıcılarla çalışma


Tarayıcı olarak Internet Explorer’ı tercih etmiyorsanız ya da Microsoft dışı tarayıcılar için
kod yazıyorsanız, farklı bir kod gereklidir. Aslında, Liste 1’de gördüğünüz gerçekten basit
olan kod satırı işinizi görür:

var xmlHttp = new XMLHttpRequest object;.

Daha basit olan bu satır, Mozilla, Firefox, Safari, Opera ve bir şekilde Ajax’ı destekleyen
Microsoft dışı birçok tarayıcıda bir XMLHttpRequest nesnesi yaratır.

Özet
İşin püf noktası tüm tarayıcıların desteklenmesidir. Kim yalnızca Internet Explorer’da ya da
yalnızca Windows dışı tarayıcılarda çalışan bir uygulama yazmak ister ki? Daha da kötüsü,
uygulamanızı iki kere yazmak ister misiniz? Tabii ki hayır! İşte bu nedenle, kodunuz hem
Internet Explorer, hem de Microsoft dışı tarayıcıları destekler. Liste 4 bunu yapmak için
gerekli olan kodu gösterir.

Liste 4. XMLHttpRequest nesnesini birden çok tarayıcı için yaratma

/* Create a new XMLHttpRequest object to talk to the Web server */


var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {


xmlHttp = new XMLHttpRequest();
}

Şimdilik, açıklamaları ve @cc_on; gibi garip etiketleri göz ardı edin; bunlar yalnızca
XMLHttpRequest üzerine yazacağım bir sonraki makalemde derinlemesine
inceleyebileceğiniz özel JavaScript derleyici komutlarıdır. Bu kodun temeli üç adıma ayrılır:

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 6/129


1. Yaratacağınız XMLHttpRequest nesnesine başvuruda bulunan bir xmlHttp değişkeni
yaratın.

2. Nesneyi Microsoft tarayıcılarında yaratmayı deneyin:

o Nesneyi Msxml2.XMLHTTP nesnesini kullanarak yaratmayı deneyin.

o Bu sonuç vermezse, nesneyi Microsoft.XMLHTTP nesnesini kullanarak yaratmayı deneyin.

3. xmlHttp hala oluşturulmadıysa, nesneyi Microsoft dışı bir yöntemi kullanarak yaratın.

Bu işlemin sonunda, kullanıcılarınız hangi tarayıcıyı kullanıyor olursa olsun, xmlHttp, geçerli
bir XMLHttpRequest nesnesine başvuruda bulunmalıdır.

Güvenlik hakkında
Peki ya güvenlik? Günümüzde tarayıcılar kullanıcılara güvenlik düzeylerini yükseltme,
JavaScript teknolojisini devre dışı bırakma ve tarayıcılarındaki istedikleri seçenekleri devre
dışı bırakma yeteneğini sunuyor. Bu gibi durumlarda, büyük olasılıkla kodunuz hiçbir koşulda
çalışmayacaktır. Bu durumlar için, sorunları dikkatli bir şekilde ele almanız gerekir; bu en
azından başlı başına bir yazı konusu ve daha sonra ele alacağım (uzun bir dizi olacak, değil
mi? Ama endişelenmeyin, tamamlamadan önce bunların tümünü çok iyi öğreneceksiniz).
Şimdilik, yazdığınız kod dayanıklı, ama mükemmel değil; bu kadarı bile Ajax’a başlangıç için
büyük bir adım. Daha ince ayrıntılara tekrar döneceksiniz.

Ajax dünyasında İstek/Yanıt


Şimdi Ajax’ı kavradınız ve XMLHttpRequest nesnesi ve bu nesnenin nasıl yaratıldığı
konusunda fikir sahibisiniz. Daha dikkatli okuduysanız, sunucudaki Web uygulamalarıyla
iletişim kuranın, doğrudan ilgili uygulamaya sunulan HTML formu değil, JavaScript
teknolojisi olduğunu fark etmişsinizdir.

Burada eksik kalan nokta nedir? XMLHttpRequest nesnesinin gerçekte nasıl kullanıldığı. Bu
kod yazdığınız her Ajax uygulamasında bir şekilde kullanacağınız çok önemli bir kod
olduğundan Ajax’ta basit bir istek/yanıt modelinin nasıl olduğuna hızlıca bakalım.

İstekte bulunma
Yeni XMLHttpRequest nesneniz hazır. Öncelikle, Web sayfanızın çağrı yapabileceği (bir
kullanıcı metin yazarken ya da menüden bir seçeneği belirlerken olduğu gibi) bir JavaScript
yöntemi gerekir. Sonra, hemen hemen tüm Ajax uygulamalarınızda aynı temel anahattı
izleyeceksiniz:

1. Web formunda gerek duyduğunuz tüm verileri alın.

2. Bağlanılacak URL’yi oluşturun.

3. Sunucuyla bir bağlantı açın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 7/129


4. Sunucuya işi tamamlandığında çalıştırması için bir işlev belirleyin.

5. İsteği gönderin.

Liste 5 bu işlemleri bu sırayla gerçekleştiren bir Ajax yöntemi örneğini gösterir:

Liste 5. Ajax ile istekte bulunma

function callServer() {
// Get the city and state from the web form
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
// Only go on if there are values for both fields
if ((city == null) || (city == "")) return;
if ((state == null) || (state == "")) return;

// Build the URL to connect to


var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" +
escape(state);

// Open a connection to the server


xmlHttp.open("GET", url, true);

// Setup a function for the server to run when it's done


xmlHttp.onreadystatechange = updatePage;

// Send the request


xmlHttp.send(null);
}

Bu örneğin büyük bir bölümü açıklama gerektirmeyecek şekilde açıktır. Kodun ilk bölümü
temel JavaScript kodunu kullanarak birkaç form alanının değerlerini ele alıyor. Ardından,
kod, bağlantı hedefi olarak bir PHP komut dosyası oluşturuyor. Basit GET parametreleri
kullanılarak komut dosyasının URL’sinin nasıl belirlendiğine, ardından (formdaki) city (ilçe)
ve state (il) değerlerinin bu isteğe nasıl eklendiğine dikkat edin.

Bir sonraki adımda, bir bağlantı açılır; burası, XMLHttpRequest nesnesinin yeniden devreye
girdiği ilk yerdir. Bağlantı yöntemi (GET) ve bağlanılacak URL belirtilir. Son parametre, true
olarak belirlendiğinde, eşzamanlı olmayan bir bağlantı (böylece bunu Ajax yaparak) ister.
False değerini kullandıysanız, istek yapıldığında kod sunucuyu bekler ve yanıt alana kadar
devam etmez. Bu değer true olarak belirlendiğinde, sunucu arka planda bu isteği işlerken
kullanıcılarınız formu kullanmaya (hatta başka JavaScript yöntemlerini çağırmaya) devam
edebilirler.

xmlHttp nesnesinin onreadystatechange özelliği (hatırlarsanız, sizin XMLHttpRequest


nesnesi örneğinizdi) sunucuya, çalışmayı bitirdiğinde (5 dakika ya da 5 saat içinde olabilir) ne
yapacağını bildirmenizi sağlar. Kod sunucuyu beklemeyeceğinden, sunucuya yanıt
verebilmeniz için sunucunun ne yapacağını bilmesini sağlamanız gerekir. Bu durumda,
sunucu isteğinizi işlemeyi bitirdiğinde updatePage() adlı belirli bir yöntem başlatılır.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 8/129


Son olarak, bir null değeriyle send() komutu çağrılır. İstek URL’sine sunucuya
gönderilecek verileri (ilçe ve il) eklediğiniz için, istekte herhangi birşey göndermeniz
gerekmez. Bu işlem isteğinizi başlatır ve sunucu, yapmasını istediğiniz işlemi yapabilir.

Bu işlem bir fikir sahibi olmanızı sağlamadıysa, ne kadar düz ve basit olduğuna bakın!
Ajax’ın eşzamanlı olmayan doğasının anlaşılmasından başka, göreceli olarak basit bir işlem.
Karmaşık http istek/yanıt kodu yerine size daha yararlı uygulamalara ve arabirimlere
yoğunlaşma özgürlüğü tanımasını takdir edeceksiniz.

Liste 5’teki kod göründüğü kadar kolaydır. Veriler basit metinlerdir ve istek URL’sinin
parçası olarak eklenebilirler. Daha karmaşık olan POST yerine GET komutu isteği gönderir.
Eklenecek XML ya da içerik başlıkları yok, isteğin gövdesinde gönderilecek veri yok; diğer
bir deyişle, bu Ajax Ütopyası.

Korkmayın; bu dizinin ilerleyen bölümlerinde işler daha karmaşık bir hal alacak. POST
isteklerini göndermeyi, istek üstbilgilerini ve içerik türlerini belirlemeyi, iletinizde XML’i
kodlamayı, isteğinize güvenlik eklemeyi ve burada sıralaması zaman alacak daha birçok
işlemi öğreneceksiniz. Şimdilik kafanızı zor işlemlerle yormayın; temel ilkeleri kavramaya
çalışın, kısa bir süre sonra tam donanımlı bir Ajax araç deposu oluşturacaksınız.

İsteğin işlenmesi

Artık sunucunun yanıtıyla çalışmanız gerekiyor. Bu aşamada yalnızca iki noktayı bilmeniz
gerekir:

• xmlHttp.readyState özelliği 4 oluncaya kadar hiçbir şey yapmayın.


• Sunucu yanıtını xmlHttp.responseText özelliğinin içine ekler.

Bu hazır durumlardan ilki bir sonraki yazının ana konusu; bir HTTP isteğinin aşamaları
hakkında bilmek istediğinizden daha fazlasını öğreneceksiniz. Şimdilik, yalnızca belirli bir
değeri (4) kontrol ederseniz, işler düzgün gider (ve bir sonraki yazının konusunu dört gözle
beklersiniz). Sunucunun yanıtını almak için xmlHttp.responseText özelliğinin kullanılması
olan ikinci nokta kolaydır. Liste 6’da, sunucunun Liste 5’te gönderilen değerlere dayanarak
çağırabileceği bir yöntem örneklenir.

Liste 6. Sunucunun yanıtını işleme

function updatePage() {
if (xmlHttp.readyState == 4) {
var response = xmlHttp.responseText;
document.getElementById("zipCode").value = response;
}
}

Yine, bu kod da çok zor ya da karmaşık değildir. Sunucunun doğru olan hazır durumla
kendini çağırmasını bekler, ardından sunucunun döndürdüğü değeri (bu örnekte, kullanıcının
girdiği ilçe ve ilin posta kodu) kullanarak başka bir form alanının değerini belirler. Sonuç
olarak, zipCode alanında birden posta kodu görünür (ama kullanıcının hiçbir zaman bir

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 9/129


düğmeyi tıklatması gerekmemiştir!). Bu daha önce söz ettiğim masaüstü uygulaması hissidir.
Hızlı yanıt verebilme, dinamik görünüş ve daha başka özelliklerin tümünü Ajax kodu
sağlıyor.

Gözlemci okuyucular zipCode alanının normal bir metin alanı olduğunu fark etmiş olabilirler.
Sunucu posta kodunu döndürdüğünde ve updatePage() yöntemi bu alanın değerini ilçe/il
posta koduyla belirlediğinde, kullanıcılar bu değeri başka bir değerle değiştirebilirler. Bunun
iki nedeni vardır: Örnekteki öğelerin basit olmasını sağlamak ve size bazen kullanıcıların, bir
sunucunun söylediğini değiştirebilmelerini istediğinizi göstermek. Her iki nedeni de dikkate
alın; çünkü bunlar iyi bir kullanıcı arabirimi tasarımı için önemli özelliklerdir.

Web formunu ekleme


Peki, söz etmediğimiz neler kaldı? Aslında, çok fazla şey kalmadı. Kullanıcının bir forma
girdiği bilgileri alan, sunucuya gönderen, iletişim kuracağı başka bir JavaScript yöntemi
sağlayan ve bir yanıtı işleyen, hatta bu yanıt geri geldiğinde bir alanın değerini belirleyen bir
JavaScript yöntemini öğrendiniz. Geriye kalan tek şey ilk JavaScript yöntemini çağırmak ve
tüm süreci başlatmak. Tabii HTML formunuza bir düğme de ekleyebilirsiniz ama bu biraz
demode olmaz mı, ne dersiniz? Liste 7’deki gibi JavaScript teknolojisinden yararlanın.

Liste 7. Bir Ajax işlemini başlatma

<form>
<p>City: <input type="text" name="city" id="city" size="25"
onChange="callServer();" /></p>
<p>State: <input type="text" name="state" id="state" size="25"
onChange="callServer();" /></p>

<p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5"


/></p>
</form>

Bunun da diğerleri gibi oldukça rutin bir kod olduğunu düşünüyorsanız, haklısınız, öyle! Bir
kullanıcı ilçe ve il alanına yeni bir değer girdiğinde, callServer() yöntemi devreye girer ve
Ajax eğlencesi başlar. Birşeyleri kavramaya başladınız mı? Güzel; amacımıza ulaştık!

Sonuç
Bu aşamada, büyük olasılıkla çıkıp ilk Ajax uygulamanızı yazmaya hazır olmayacaksınız;
tabii en azından Kaynaklar bölümünde gerçekten inceleme yapmaya istekli değilseniz.
Bununla birlikte, bu uygulamaların nasıl çalıştığıyla ve XMLHttpRequest nesnesiyle ilgili
temel bilgileri kavramaya başlayabilirsiniz. Sonraki makalelerde, bu nesne, JavaScript ve
sunucu arasındaki iletişimi yönetme, HTML formlarıyla çalışma, hatta DOM’la ilgili temel
kavramlar konusunda derinlemesine bilgi sahibi olacaksınız.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 10/129


Şimdilik, yine de, Ajax uygulamalarının ne kadar güçlü olabileceğini düşünmeye zaman
ayırın. Size yalnızca bir düğmeyi tıklattığınızda değil, bir alana veri girdiğinizde, birleşik giriş
kutusundan bir seçim yaptığınızda, hatta farenizi ekranda sürüklediğinizde de yanıt veren bir
Web formu hayal edin. Eşzamanlı olmayan teriminin tam olarak ne anlama geldiğini düşünün;
çalışan ve sunucunun, isteklerine yanıt vermesini beklemeyen bir JavaScript kodunu düşünün.
Ne tür sorunlarla karşılaşabilirsiniz? Hangi alanlarda dikkatli olmanız gerekir? Ve
formlarınızın tasarımı bu yeni programlama yaklaşımından nasıl etkilenecek?

Bu konular üzerinde kayda değer zaman harcarsanız, kesip yapıştırabileceğiniz ve gerçekte


anlamadığınız bir uygulamaya geçireceğiniz koda sahip olmanın ötesinde avantajlar elde
edebilirsiniz. Bir sonraki makalede, bu fikirleri uygulamaya geçireceksiniz ve size,
uygulamaların burada anlatıldığı gibi çalışmasını sağlamanız için gereksinim duyacağınız
kodla ilgili ayrıntıları vereceğim. O zamana kadar Ajax’ın olanaklarının tadını çıkarın.

Kaynaklar
Bilgi

• Adaptive Path kullanıcı arabirimi tasarımı alanındaki lider şirketlerden biridir; bu


şirketin sayfalarını dikkatle okuyarak Ajax hakkında birçok bilgi edinebilirsiniz.
• Ajax teriminin nereden geldiğini merak ediyorsanız, kaynak olarak Jesse James
Garrett ve Ajax hakkındaki mükemmel makalelerine (bunun gibi) bakın.
• XMLHttpRequest nesnesiyle ilgili bu harika makaleyi inceleyip, XMLHttpRequest
nesnesi üzerinde yoğunlaşarak bu dizinin bir sonraki yazısı için hazırlık yapabilirsiniz.
• Internet Explorer kullanıyorsanız, Microsoft Developer Network's XML Developer
Center olanağında işinize yarayacak birçok şey bulabilirsiniz.
• Ajax for Java developers: Build dynamic Java applications (developerWorks, Eylül
2005), sayfayı yeniden yükleme çıkmazını çözen dinamik Web uygulaması yaratma
alanında çığır açan bir yaklaşımı anlatır.
• Ajax for Java developers: Java object serialization for Ajax (developerWorks, Ekim
2005) Ajax uygulamarında verilerin diziselleştirilmesine yönelik beş yöntemi açıklar.
• Using Ajax with PHP and Sajax (developerWorks, Ekim 2005) Ajax ve PHP’yi
kullanarak içeriği dinamik olarak güncelleyen zengin Web uygulamaları geliştirmekle
ilgillenenlere yönelik eğitici bir yayındır.
• Call SOAP Web services with AJAX, Part 1: Build the Web services client
(developerWorks, Ekim 2005) Web tarayıcısı tabanlı bir SOAP Web hizmetleri
istemcisinin Ajax tasarım modeli kullanılarak nasıl uygulanacağını anlatır.
• XML Matters: Beyond the DOM (developerWorks, Mayıs 2005) Document Object
Model’in (Belge Nesne Modeli) dinamik Web uygulamaları oluşturma yöntemi olarak
kullanılmasının ayrıntılı olarak açıklar.
• Build apps with Asynchronous JavaScript with XML, or AJAX (developerWorks,
Kasım 2005) Ajax kullanılarak gerçek zamanlı kimlik doğrulama yapabilen Web
uygulamalarının nasıl geliştirildiğini gösterir.
• Ajax for Java developers: Ajax with Direct Web Remoting (developerWorks, Kasım
2005) AJAX’ın ağır karmaşık yükünün nasıl otomatikleştirileceğini gösterir.
• OSA Foundation AJAX/JavaScript kitaplıklarında araştırma yapan katılımcı bir Web
sitesine (wiki) sahiptir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 11/129


• XUL Planet’taki object reference (nesne başvurusu) bölümü XMLHttpRequest
nesnesiyle (XML nesnelerinin yanı sıra DOM, CSS, HTML, Web Service ve
Windows ve Navigation nesneleri gibi diğer türler dahil) ilgili ayrıntılı bilgileri içerir.
• Bazı temel Ajax ilkeleri hakkında ayrıntılı bilgi edinmek için güzel bir stratejik teknik
yazıyı okuyabilirsiniz.
• Flickr.com adresinde çarpıcı Ajax uygulamarından birini çevrimiçi olarak
görebilirsiniz.
• Google’un GMail’i Ajax’ın devrim yaratan Web uygulamalarından biridir.
• Head Rush Ajax (O'Reilly Media, Inc., Şubat 2006) bu makalede ve dizide özetlenen
fikirleri (ve daha birçok şeyi) alarak size yeni ve Head First ödüllü biçimde sunar.
• JavaScript: The Definitive Guide, 4. Basım (O'Reilly Media, Inc., Kasım 2001)
JavaScript dili ve dinamik Web sayfalarıyla çalışmak konularında zengin bir
kaynaktır.
• developerWorks Web Architecture zone (Web mimarisi bölgesi) çeşitli Web tabanlı
çözümleri ele alan makaleler üzerinde yoğunlaşır.

Tartışma

• Tartışma forumuna katılın.


• Ajax.NET Professional Ajax’ı tüm yönleriyle ele alan harika bir Web günlüğüdür.
• developerWorks Web günlüklerine katılarak developerWorks topluluğuna girin.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 12/129


Ajax Konusunda Uzmanlaşma, Bölüm 2:
JavaScript ve Ajax ile zamanuyumsuz
istekler oluşturma
Web istekleri için XMLHttpRequest kullanılması

Düzey: Orta

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

17 Ocak 2006

Web uygulamalarının çoğu, sunucudan tüm HTML sayfasını alan bir istek/yanıt modelini
kullanır. Sonuçta kullanıcı bir düğmeyi tıklatır, sunucuyu bekler, başka bir düğmeyi tıklatır ve
biraz daha bekler. Ajax ve XMLHttpRequest nesnesiyle, kullanıcıların sunucu yanıtını
beklemelerine hiçbir zaman gerek bırakmayan bir istek/yanıt modeli kullanabilirsiniz. Bu
makalede, Brett McLaughlin, çapraz tarayıcı yöntemiyle XMLHttpRequest örneklerinin nasıl
oluşturulacağını, isteklerin oluşturulmasını ve gönderilmesini ve sunucuya yanıt verilmesini
gösteriyor.

Bu dizinin son makalesinde (bağlantılar için bkz. Kaynaklar), Ajax uygulamalarına giriş
yapılmış ve Ajax uygulamalarının kullandığı bazı temel kavramlara bakılmıştı. Bunun
merkezinde, önceden biliyor olabileceğiniz birçok teknoloji vardır: JavaScript, HTML ve
XHTML, biraz dinamik HTML ve hatta, biraz DOM (Document Object Model; Belge Nesne
Modeli). Bu makalede, uzak mesafeden konuya yaklaşıp özel Ajax ayrıntılarına
odaklanacağım.

Bu makalede, Ajax'la ilişkili tüm nesnelerin ve programlama yaklaşımlarının en temelinden


başlayacağız: XMLHttpRequest nesnesi. Bu nesne, gerçekten de tüm Ajax uygulamaları
arasında tek ortak iş parçacığıdır ve -- tahmin edebileceğiniz gibi -- programlama yeteneğinizi
mümkün olan sınırlara götürebilmek için bu nesneyi anlamak isteyeceksiniz. Aslında, bazen
XMLHttpRequest nesnesini doğru kullanmak için, açıkça XMLHttpRequest nesnesini
kullanmayacaksınız. Peki bütün bunlar da ne demek oluyor?

Bir bakışta Web 2.0

Öncelikle, kodun içine dalmadan bu genel bakışın son kısmını ele alalım -- Web 2.0
konusunda her şeyin kafanızda net olduğundan emin olun. Web 2.0 terimini duyduğunuzda,
sormanız gereken ilk şey "Web 1.0 nedir?" olmalıdır. Web 1.0 terimi çok sık duyulmasa da,
çok belirgin bir istek ve yanıt modelinin kullanıldığı geleneksel Web için kullanılmaktadır.
Örneğin, Amazon.com'a gidin ve bir düğmeyi tıklatın ya da bir arama terimi girin. Sunucuya
bir istek gönderilir ve tarayıcınıza bir yanıt gelir. Bu istek, kitaplar ve başlıklardan oluşan bir
listeden çok daha fazlasını içerir; aslında bu başka bir tam HTML sayfasıdır. Sonuç olarak,
Web tarayıcınızın ekranı bu yeni HTML sayfasıyla yeniden çizilirken bazı yanıp sönen
şekiller görürsünüz. Aslında, gördüğünüz her bir sayfayla tanımlanan istek ve yanıtı açıkça
görebilirsiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 13/129


Web 2.0, bu gözle görülür geri ve ileri kavramını (çok geniş bir ölçeğe kadar) bir yana bırakır.
Örneğin, Google Maps ya da Flickr gibi bir siteyi ziyaret edin (Kaynaklar içinde, Ajax
tarafından desteklenen bu Web 2.0 sitelerine bağlantılar yer alır). Google Maps'te, harita
üzerinde fareyi sürükleyerek gezinebilir ve çok küçük bir yeniden çizimle haritayı
yakınlaştırıp uzaklaştırabilirsiniz. Elbette, burada da istekler ve yanıtlar vardır, ancak bunların
tümü sahne arkasından yürütülmektedir. Bir kullanıcı olarak sizin gördüğünüz, çok daha
güzel ve daha çok bir masaüstü uygulamasını kullanmak gibidir. Web 2.0'dan söz edildiğinde
gördüğünüz şey, bu yeni deneyim ve paradigmanın kendisidir.

Daha sonra, bu yeni etkileşimlerin nasıl mümkün kılınacağını düşünmeniz gerekir. Tabii, hala
isteklerde bulunmanız ve yanıtları almanız gerekir, ancak yavaş ve aksak bir Web arabirimi
algılamasını veren şey, her bir istek/yanıt etkileşiminde HTML'in yeniden çizilmesidir. Daha
net bir şekilde anlatırsak, tüm HTML sayfasının yerine, yalnızca ihtiyacınız olan veriler için
istekte bulunacak ve yanıtları alacak bir yaklaşıma ihtiyacınız vardır. Yeni bir tam HTML
sayfasını yalnızca, kullanıcının yeni bir sayfa görmesini istediğinizde almak isteyebilirsiniz.

Ancak etkileşimlerin çoğu, ayrıntı ekler ya da gövde metnini değiştirir ya da var olan
sayfalardaki verilerin üzerine yazar. Bu durumların tümünde, Ajax ve Web 2.0 yaklaşımı tüm
HTML sayfasını güncellemeden veri gönderip almayı mümkün kılar. Ve bu yetenek, sık sık
Web'de dolaşan kullanıcılara uygulamanızın çok daha hızlı, daha çabuk yanıt veren bir
uygulama olduğunu düşündürecek ve tekrar tekrar geri gelmelerini sağlayacaktır.

XMLHttpRequest'e Giriş

Tüm bu hokus pokusu gerçekleştirmek için XMLHttpRequest adlı JavaScript nesnesini


yakından tanımanız gerekir. Bu küçük nesne -- bir süredir bazı tarayıcılarda kullanılmaktadır -
- Web 2.0, Ajax ve önümüzdeki birkaç ay boyunca bu köşede öğreneceğiniz diğer her şeyin
temel taşıdır. Hızlı bir genel görünüm sağlamak amacıyla, bu nesneyle birlikte
kullanabileceğiniz birkaç yöntemi ve özelliği sıralayayım:

• open(): Sunucuya gönderilecek yeni bir istek hazırlar.


• send(): Bir isteği sunucuya gönderir.
• abort(): Geçerli istekten çıkar.
• readyState: Geçerli HTML hazırlık durumunu sağlar.
• responseText: Bir isteğe yanıt vermek için sunucunun gönderdiği metin.

Bunların tümünü (ya da hiçbirini) anlamazsanız üzülmeyin -- bundan sonraki birkaç makale
içinde her bir yöntem ve özellik ayrıntılarıyla anlatılacaktır. Buradan çıkarmanız gereken,
XMLHttpRequest ile ne yapacağınıza ilişkin iyi bir fikirdir. Bu yöntemlerin ve özelliklerin her
birinin, bir istek göndermeyle ve bir yanıtı işlemeyle ilgili olduğuna dikkat edin. Aslında,
XMLHttpRequest nesnesinin her yöntemini ve özelliğini gördükçe, bunların tümünün o çok
basit istek/yanıt modeliyle ilişkili olduğunu anlayacaksınız. Açıkçası, inanılmaz bir GUI
nesnesiyle ya da kullanıcı etkileşimi yaratmak için süper gizli bir yaklaşımla ilgili bilgi
almayacaksınız; basit istekler ve basit yanıtlarla çalışacaksınız. Bu kulağa heyecan verici
gelmeyebilir, ancak bu tek nesnenin dikkatli bir şekilde kullanılması uygulamalarınızı
tamamen değiştirebilir.

Yeninin basitliği

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 14/129


Öncelikle, yeni bir değişken yaratmanız ve bunu, XMLHttpRequest nesnesinin bir örneğine
atamanız gerekir. Bu JavaScript'te oldukça kolaydır; nesne adında new (yeni) anahtar
sözcüğünü kullanmanız yeterlidir (Liste 1'de olduğu gibi).

Liste 1. Yeni bir XMLHttpRequest nesnesi yaratma


<script language="javascript" type="text/javascript">
var request = new XMLHttpRequest();
</script>

Çok zor değildi, değil mi? Unutmayın, JavaScript, değişkeninin üzerine yazılmasını
gerektirmez, bu nedenle Liste 2'deki gibi bir şeye ihtiyacınız yoktur (bu nesneyi Java
yaratsaydınız, böyle yapmanız gerekebilirdi).

Liste 2. XMLHttpRequest nesnesi yaratmaya ilişkin sözde Java kodu


XMLHttpRequest request = new XMLHttpRequest();

JavaScript'te var ile bir değişken yaratır, buna bir ad verir ("request" gibi) ve daha sonra
bunu, yeni XMLHttpRequest örneğine atarsınız. Bu noktadan sonra nesneyi işlevlerinizde
kullanabilirsiniz.

Hata işleme

Gerçek yaşamda, işler kötü gidebilir ve bu kod, hata işleme özelliği sağlamaz. Bu nesneyi
yaratmak ve işler ters giderse nesneyi hatalı olarak ayırmak biraz daha iyi bir yaklaşımdır.
Örneğin, eski tarayıcıların birçoğu (ister inanın ister inanmayın, insanlar hâlâ Netscape
Navigator programının eski sürümlerini kullanmaya devam ediyorlar) XMLHttpRequest
nesnesini desteklemez ve bu kullanıcılara, bir şeyin ters gittiğini bildirmeniz gerekir. Liste
3'te, bu nesnenin, hata oluştuğunda JavaScript uyarısı verecek şekilde nasıl yaratılacağı
gösterilmektedir.

Liste 3. XMLHttpRequest nesnesini bazı hata işleme yetenekleriyle yaratma


<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (failed) {
request = false;
}

if (!request)
alert("Error initializing XMLHttpRequest!");
</script>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 15/129


Bu adımların her birini tam olarak anladığınızdan emin olun:

1. Request adlı yeni bir değişken oluşturun ve buna, bir false (yanlış) değeri atayın.
XMLHttpRequest nesnesinin henüz yaratılmadığını belirten bir koşul olarak false
(yanlış) değerini kullanacaksınız.
2. Bir try/catch (dene/yakala) bloğu ekleyin:
1. XMLHttpRequest nesnesini yaratmayı deneyin.
2. Başarısız olursanız (catch (failed)), request değişkeninin false (yanlış)
değerinde kaldığından emin olun.
3. Request değişkeninin hâlâ false (yanlış) değerinde olup olmadığına bakın (işler
yolundaysa, bu değerde kalmış olmayacaktır).
4. Bir sorun varsa (ve request false değerindeyse), kullanıcılara bir sorun olduğunu
bildirmek için bir JavaScript uyarısı kullanın.

Bu oldukça basittir; çoğu JavaScript ve Web geliştiricisi için konuyu anlamak, ilgili konuları
okuyup yazılar yazmaktan çok daha kısa sürer. Artık XMLHttpRequest nesnesi yaratan ve
hata kabul etmeyen bir kod parçanız var, üstelik ters giden şeylerle ilgili size bilgi de veriyor.

Microsoft ile çalışma

Her şey yolunda gibi görünüyor ... en azından bu kodu Internet Explorer'da deneyinceye
kadar. Bunu denerseniz, Şekil 1'dekine benzer, berbat görünen bir sonuç alırsınız.

Şekil 1. Internet Explorer hata bildirimi

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 16/129


Microsoft düzgün çalışıyor mu?
Ajax ve Microsoft'un bu alandaki
giderek artan ilgisine ve varlığına
ilişkin çok şey yazıldı. Aslında,
Microsoft'un en yeni Internet Explorer
sürümünün (sürüm 7.0'ın 2006'nın
sonlarına doğru çıkması bekleniyor)
XMLHttpRequest nesnesini doğrudan
desteklemesi ve tüm Msxml2.XMLHTTP
yaratma kodu yerine new (yeni)
anahtar sözcüğünü kullanmanıza izin
vermesi bekleniyor. Yine de çok
heyecanlanmayın; eski tarayıcıları
desteklemeyi sürdürmeniz
gerektiğinden, tarayıcılar arası kod
yakın bir gelecekte ortadan kalkacak
gibi görünmüyor.

Görünen o ki, bir şeyler ters gidiyor; Internet Explorer'ın modası geçmiş bir tarayıcı olduğu
söylenemez ve dünyanın yaklaşık %70'i Internet Explorer kullanmaya devam ediyor. Diğer
bir deyişle, Microsoft ve Internet Explorer'ı desteklemezseniz, Web dünyasında çok da
başarılı olamazsınız. Bu nedenle, Microsoft'un tarayıcılarıyla çalışmak için farklı bir
yaklaşıma ihtiyacınız var.

Görünüşe göre Microsoft Ajax'ı destekliyor, ancak kendi XMLHttpRequest sürümüne farklı
bir ad veriyor. Aslında, bunun için birkaç farklı ad kullanıyor. Internet Explorer'ın daha yeni
bir sürümünü kullanıyorsanız, Msxml2.XMLHTTP adlı nesneyi kullanmanız gerekir; bazı eski
Internet Explorer sürümleri Microsoft.XMLHTTP nesnesini kullanır. Bu iki nesne tipini
desteklemeniz gerekir (bu arada Microsoft dışındaki tarayıcıların desteğini de
kaybetmemelisiniz). Daha önce gördüğünüz koda Microsoft desteği ekleyen Liste 4'e bakın.

Liste 4. Microsoft tarayıcıları için destek ekleme


<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}

if (!request)
alert("Error initializing XMLHttpRequest!");

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 17/129


</script>

Bu dolambaçlı yollarda kaybolmak oldukça kolay olduğundan ben size adım adım yol
göstereceğim:

1. Request adlı yeni bir değişken oluşturun ve buna, bir false (yanlış) değeri atayın.
Koşul için XMLHttpRequest nesnesinin henüz yaratılmadığını belirten false (yanlış)
değerini kullanın.
2. Bir try/catch (dene/yakala) bloğu ekleyin:
1. XMLHttpRequest nesnesini yaratmayı deneyin.
2. Başarısız olursa (catch (trymicrosoft)):
1. Microsoft'un daha yeni sürümlerini kullanarak Microsoft uyumlu bir
nesne yaratmayı deneyin (Msxml2.XMLHTTP).
2. Başarısız olursa (catch (othermicrosoft)), Microsoft'un eski
sürümlerini kullanarak Microsoft uyumlu bir nesne yaratmayı deneyin
(Microsoft.XMLHTTP).
3. Başarısız olursanız (catch (failed)), request değişkeninin false (yanlış)
değerinde kaldığından emin olun.
3. Request değişkeninin hâlâ false (yanlış) değerinde olup olmadığına bakın (işler
yolundaysa, bu değerde kalmayacaktır).
4. Bir sorun varsa (ve request false değerindeyse), kullanıcılara bir sorun olduğunu
bildirmek için bir JavaScript uyarısı kullanın.

Kodunuzdaki bu değişiklikleri yaptıktan sonra Internet Explorer'da bir deneme daha yapın;
yarattığınız formu (hata iletisi olmadan) görmeniz gerekir. Benim denememde, sonuç Şekil
2'deki gibiydi.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 18/129


Şekil 2. Internet Explorer olağan bir şekilde çalışıyor

Statik - dinamik karşılaştırması

Liste 1, 3 ve 4'e tekrar bakın ve bu kodun doğrudan script biçim imlerinin içine
yerleştirildiğine dikkat edin. JavaScript böyle kodlandığında ve bir yöntem ya da işlev
gövdesine yerleştirilmediğinde, buna statik JavaScript denir. Bu, kodun, sayfa kullanıcıya
görüntülenmeden önce çalışmaya başladığı anlamına gelir. (Belirtimden, kodun tam olarak ne
zaman çalıştığı ve tarayıcıların işlemleri ne zaman farklı gerçekleştirdikleri yüzde yüz net
değildir; ancak kodun, kullanıcıların sayfanızla etkileşime girmeden önce çalışması garanti
edilir.) Birçok Ajax programcısı genellikle XMLHttpRequest nesnesini böyle yaratır.

Bunu belirttikten sonra, bu kodu kesinlikle Liste 5'teki gibi bir yönteme yerleştirebilirsiniz.

Liste 5. XMLHttpRequest yaratma kodunu bir yönteme taşıma


<script language="javascript" type="text/javascript">

var request;

function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 19/129


} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}

if (!request)
alert("Error initializing XMLHttpRequest!");
}
</script>

Kod bu şekilde kurulduğunda, herhangi Ajax çalışması gerçekleştirmeden önce bu yöntemi


çağırmanız gerekir. Bu nedenle, Liste 6'daki gibi bir şey hazırlamalısınız.

Liste 6. XMLHttpRequest yaratma yönetimi kullanma


<script language="javascript" type="text/javascript">

var request;

function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}

if (!request)
alert("Error initializing XMLHttpRequest!");
}

function getCustomerInfo() {
createRequest();
// Do something with the request variable
}
</script>

Bu kodla ilgili tek sorun -- ve çoğu Ajax programcısının bu yaklaşımı kullanmamasının


nedeni -- bunun hata bildirimini geciktirmesidir. 10 ya da 15 alandan, seçim kutusundan, vb.
oluşan karmaşık bir formunuz olduğunu varsayın ve kullanıcı alan 14'e (formun altlarında) bir
metin girdiğinde Ajax kodunun bir kısmını çalıştırırsınız. Bu noktada, getCustomerInfo()
çalışır, bir XMLHttpRequest nesnesi yaratmayı dener ve (bu örnekte) başarısız olur. Daha

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 20/129


sonra, kullanıcıya, (bir sürü sözcükle) bu uygulamayı kullanamayacaklarını belirten bir uyarı
gönderilir. Ancak kullanıcı forma veri girerek zaman harcamıştır! Bu oldukça can sıkıcı bir
durumdur ve canlarını sıkmak, kullanıcıların sitenize geri gelmelerini engelleyebilecek bir
durumdur.

Statik JavaScript kullandığınızda, kullanıcı sayfanıza gelir gelmez bir hata iletisi alır. Bu da
can sıkı değil mi? Belki; Web uygulamanızın tarayıcılarında çalışmaması kullanıcıları
kızdırabilir. Ancak, aynı hatayı bilgi girmek için harcadıkları 10 dakikanın sonunda
vermekten kesinlikle çok daha iyidir. Yalnızca bu nedenden, size kodunuzu statik olarak
hazırlamanızı ve kullanıcılara olası sorunlarla ilgili erkenden bilgi vermenizi öneririm.

XMLHttpRequest ile istek gönderme

İstek nesneniz hazırlandıktan sonra, istek/yanıt döngüsünü başlatabilirsiniz. Unutmayın,


XMLHttpRequest nesnesinin tek amacı isteklerde bulunmanızı ve yanıt almanızı sağlamaktır.
Diğer şeyler -- kullanıcı arabirimini değiştirmek, resim geçişleri, hatta sunucunun geri
gönderdiği verileri yorumlamak -- JavaScript, CSS ya da sayfalarınızdaki diğer kodların
görevidir. XMLHttpRequest kullanıma hazır olduğunda, bir sunucuya bir istek
gönderebilirsiniz.

Kum havuzuna hoşgeldiniz

Ajax, kum havuzu olarak bilinen bir güvenlik modeli kullanır. Sonuç olarak, Ajax kodunuz
(ve özellikle XMLHttpRequest nesnesi) yalnızca çalıştığı etki alanına istekte bulunabilir.
Yakında yayınlanacak bir makalede güvenlik ve Ajax ile ilgili çok daha fazla şey
öğreneceksiniz, ama şimdilik bilmeniz gereken yerel makinenizde çalışan kodun, yalnızca
yerel makinenizdeki sunucu tarafı komut dosyalarına istekte bulunabileceğidir. Ajax kodunuz
www.breakneckpizza.com üzerinde çalışıyorsa, bunun www.breakneckpizza.com üzerinde
çalışan komut dosyalarına istek göndermesi gerekir.

Sunucu URL'sini ayarlama

İlk olarak belirlemeniz gereken bağlanılacak sunucunun URL'sidir. Bu Ajax'a özel bir şey
değildir (açıkçası şimdiye kadar URL oluşturmayı öğrenmiş olmanız gerekir) ancak yine de
bağlantı kurmak için bu gereklidir. Çoğu uygulamada, bu URL'yi kullanıcılarınızın üzerinde
çalıştıkları formdan alınan verilerle bazı statik veri takımlarının birleşiminden
oluşturacaksınız. Örneğin, Liste 7'de telefon numarası alanındaki değeri alan ve bu verileri
kullanarak URL oluşturan bir JavaScript kodu gösterilmektedir.

Liste 7. Bir istek URL'si oluşturma


<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 21/129


} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}

if (!request)
alert("Error initializing XMLHttpRequest!");

function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
}
</script>

Buradaki hiçbir şey kafanızı karıştırmamalıdır. Öncelikle, kod phone (telefon) adlı yeni bir
değişken yaratır ve bu değişkene, tanıtıcısı "phone" (telefon) olan form alanının değerini atar.
Liste 8'de, bu forma ilişkin phone (telefon) alanını ve id (tanıtıcı) özniteliğini görebileceğiniz
XHTML gösterilmektedir.

Liste 8. Break Neck Pizza formu


<body>
<p><img src="breakneck-logo_4c.gif" alt="Break Neck Pizza" /></p>
<form action="POST">
<p>Enter your phone number:
<input type="text" size="14" name="phone" id="phone"
onChange="getCustomerInfo();" />
</p>
<p>Your order will be delivered to:</p>
<div id="address"></div>
<p>Type your order in here:</p>
<p><textarea name="order" rows="6" cols="50" id="order"></textarea></p>
<p><input type="submit" value="Order Pizza" id="submit" /></p>
</form>
</body>

Ayrıca, kullanıcılar telefon numaralarını girdiklerinde ya da numarayı değiştirdiklerinde


getCustomerInfo() yönteminin başlatılması da Liste 8'de gösterilmiştir. Bu yöntem daha
sonra numarayı alır ve url değişkeninde saklanan bir URL dizisi oluşturmak için kullanılır.
Unutmayın: Ajax kodu kum havuzu yöntemini kullandığı ve yalnızca aynı etki alanına
bağlanabildiği için, URL'nizde gerçekten bir etki alanı adı olması gerekmez. Bu örnekte,
komut dosyasının adı /cgi-local/lookupCustomer.php'dir. Son olarak, telefon numarası
bu komut dosyasına bir GET parametresi olarak eklenir: "phone=" + escape(phone).

escape() yöntemini daha önce hiç görmediyseniz, doğru biçimde düz metin olarak
gönderilemeyecek karakterlerden kaçınmak için kullanılır. Örneğin, telefon numarasındaki
boşluklar %20 karakterlerine dönüştürülür ve karakterlerin URL içinde aktarılmasını sağlar.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 22/129


İhtiyacınız olan sayıda parametre ekleyebilirsiniz. Örneğin, başka bir parametre eklemek
isterseniz, bunu URL'ye ekleyin ve parametreleri ve (&) karakteriyle birbirinden ayırın [ilk
parametre komut dosyası adından bir soru işaretiyle (?) ayrılır].

İsteği açma

open() açıyor mu?


Internet geliştiricileri, open()
yönteminin tam olarak ne işe yaradığı
konusunda bir anlaşmaya
varamamışlardır. Yapmadığı şey, bir
isteği gerçekten açmaktır.
XHTML/Ajax sayfanızla sayfanın
bağlandığı komut dosyası arasındaki
ağ ve veri aktarımını izlerseniz,
open() yöntemi çağrıldığında hiç
trafik görmezsiniz. Neden bu adın
seçildiği tam olarak bilinmese de iyi
bir seçim olduğu söylenemez.

Bağlanılacak bir URL ile, isteği yapılandırabilirsiniz. Bunu, XMLHttpRequest nesnenizde


open() yöntemini kullanarak gerçekleştireceksiniz. Bu yöntem, en çok beş parametre kabul
eder:

• request-type: Gönderilecek isteğin tipi. Genellikle GET ya da POST değerleri gönderilir,


ancak HEAD istekleri de gönderebilirsiniz.
• url: Bağlanılacak URL.
• asynch: İsteğin zamanuyumsuz olmasını istiyorsanız true (doğru), zamanuyumlu
olmasını istiyorsanız false (yanlış) değerinde olmalıdır. Bu parametre isteğe bağlıdır
ve varsayılan değer olarak true (doğru) değerindedir.
• username: Kimlik doğrulaması gerekiyorsa, kullanıcı adını burada belirtebilirsiniz. Bu
isteğe bağlı bir parametredir ve herhangi bir varsayılan değeri yoktur.
• password: Kimlik doğrulaması gerekiyorsa, parolayı burada belirtebilirsiniz. Bu isteğe
bağlı bir parametredir ve herhangi bir varsayılan değeri yoktur.

Genellikle, bu parametrelerin ilk üçü kullanılır. Aslında, zamanuyumsuz bir istekte bulunmak
istediğinizde bile üçüncü parametre için "true" (doğru) değerini belirlemeniz gerekir. Bu
varsayılan ayardır, ancak isteğin zamanuyumsuz olup olmadığını belirtmek her zaman için
kendi belgelendirmelerinizde yararlı olabilir.

Hepsini bir araya topladığınızda genellikle Liste 9 gibi görünen bir satır ortaya çıkar.

Liste 9. İsteği açma


function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
}

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 23/129


URL'yi belirledikten sonra gerisi önemsizdir. Birçok istek için GET'in kullanılması yeterlidir
(sonraki makalelerde POST kullanmak isteyebileceğiniz durumları göreceksiniz); open()
yöntemini kullanmak için, URL ile birlikte, tüm gerekli olan bu kadardır.

Zamanuyumsuzluk üzerine kısa bir açıklama

Bu dizide yayınlanacak sonraki bir makalede, zamanuyumsuz kod yazma ve kullanma


üzerinde ayrıntılı bir şekilde duracağım; ancak, open() yöntemindeki bu son parametrenin
neden bu kadar önemli olduğunu anlamanızı istiyorum. Normal bir istek/yanıt modelinde --
burada Web 1.0'ı düşünün -- istemci (tarayıcınız ya da yerel makinenizde çalışan kod)
sunucuya bir istekte bulunur. Bu istek zamanuyumludur; diğer bir deyişle, istemci sunucudan
bir yanıt bekler. İstemci beklerken, genellikle beklemekte olduğunuzu gösteren birkaç
bildirim biçiminden en az birini alırsınız:

• Kum saati (özellikle Windows'ta).


• Dönen plaj topu (genellikle Mac makinelerinde).
• Uygulama donar ve bazen imleç değişir.

Web uygulamalarının aksak ya da yavaş olduğunu düşünmenizin asıl nedeni budur -- gerçek
etkileşim eksikliği. Bir düğmeye bastığınızda, gönderilen isteğe yanıt gelinceye kadar
uygulamanız kullanılamaz duruma gelir. Yoğun sunucu işlemi gerektiren bir istekte
bulunduysanız, bekleme süresi uzun olabilir (en azında günümüzün çok işlemcili, beklemesiz,
DSL dünyasında).

Bununla birlikte, zamanuyumsuz bir istek sunucunun yanıt vermesini beklemez. Bir istek
gönderirsiniz ve uygulamanız işleme devam eder. Kullanıcılar Web formuna bilgi girmeye,
diğer düğmeleri tıklatmaya devam edebilir, hatta formdan çıkabilirler. Dönen plaj topları,
kum saatleri ya da uzun süreli donan uygulamalar olmaz. Sunucu sessizce isteğe yanıt verir ve
işlem tamamlandığında, ilk istekte bulunanın, (biraz sonra göreceğiniz yöntemlerle) işlemin
tamamlandığını bilmesini sağlar. Sonuçta aksak ya da yavaş olmayan, bunun yerine yanıt
veren, etkileşimli ve daha hızlı bir uygulama ortaya çıkar. Bu Web 2.0'ın yalnızca bir
bileşenidir, ancak çok önemlidir. Tüm parlak GUI bileşenleri ve Web tasarımı paradigmaları
yavaş, zamanuyumlu istek/yanıt modelinin üstesinden gelemez.

İsteği gönderme

İstek, open() yöntemiyle yapılandırıldıktan sonra gönderilmeye hazırdır. Neyse ki isteği


göndermeye ilişkin yöntem, open() yönteminden daha doğru bir şekilde adlandırılmıştır. Bu
yönteme send() denir.

send() yalnızca tek bir parametre alır: gönderilecek içerik. Bunun üzerinde uzun uzun
düşünmeden önce, verileri URL'nin kendisinden göndermekte olduğunuzu anımsayın:

var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);

Verileri send() yöntemiyle gönderebilirsiniz, ancak verileri URL'nin kendisi üzerinden de


gönderebilirsiniz. Aslında, GET isteklerinde (olağan Ajax kullanımının yaklaşık %80'ini

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 24/129


oluşturur), verileri URL içinde göndermek çok daha kolaydır. Güvenli bilgi ya da XML
göndermeye başladığınızda, içeriği send() yöntemiyle göndermek isteyebilirsiniz (güvenli
veri ve XML iletilerini bu dizinin sonraki bir makalesinde anlatacağım). Verileri send()
yöntemiyle geçirmeniz gerekmediğinde, bu yöntemin bağımsız değişkeni için yalnızca null
(yok) değerini belirleyin. Bu makalede gördüğünüz örnekte bir istek göndermek için tüm
ihtiyacınız olan tam olarak budur (bkz. Liste 10).

Liste 10. İsteği gönderme


function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.send(null);
}

Geri çağrı yönteminin belirlenmesi

Bu noktada, yeni, devrim niteliğinde ya da zamanuyumsuz sayılabilecek çok az şey yaptınız.


open() yönteminde küçük "true" (doğru) anahtar sözcüğünün eklenmesi zamanuyumsuz bir
istek oluşturdu. Ancak bunun dışında, bu kod Java sunucu uygulamalarıyla programlamaya ve
JSP'lere, PHP ya da Perl'e dayanır. O zaman Ajax ve Web 2.0'ın büyük sırrı ne? Sır,
XMLHttpRequest nesnesinin onreadystatechange adı verilen basit bir özelliği çevresinde
döner.

Öncelikle, bu kodda yarattığınız süreci anladığınızdan emin olun (gerekiyorsa, Liste 10'u
gözden geçirin). Bir istek oluşturuldu ve gönderildi. Buna ek olarak, bu bir zamanuyumsuz
istek olduğundan JavaScript yöntemi (bu örnekte getCustomerInfo()) sunucunun yanıtını
beklemeyecektir. Kod devam edecek; bu durumda, yöntemden çıkılacak ve denetim forma
dönecek. Kullanıcılar bilgi girmeye devam edebilecekler ve uygulama sunucuyu
beklemeyecektir.

Ancak bu, ilginç bir soruyu da beraberinde getiriyor: Sunucu isteği işlemeyi bitirdiğinde ne
olacak? Yanıt, en azından kodun şu haliyle, hiçbir şey! Elbette bu iyi bir şey değil. Bu
nedenle, XMLHttpRequest tarafından gönderilen isteği işlemesi tamamlandığında sunucunun
ne yapması gerektiğini belirten bir tür yönergeye sahip olması gerekir.

JavaScript içindeki bir işleve


başvuruda bulunma
JavaScript gevşek biçimde yazılmış
bir dildir ve neredeyse her şeye bir
değişken olarak başvurabilirsiniz.
updatePage() adlı bir işlev
açıklarsanız, JavaScript bu işlev adını
da bir değişken olarak işler. Diğer bir
deyişle, kodunuzdaki işleve
updatePage adlı bir değişken olarak
başvurabilirsiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 25/129


İşte tam burada onreadystatechange özelliği devreye girer. Bu özellik bir geri çağrı
yöntemi belirleyebilmenizi sağlar. Geri çağrı (callback), sunucunun Web sayfanızın kodunu
geri çağırabilmesini sağlar (tahmin eder miydiniz?). Bu, sunucuya bir ölçüye kadar denetim
de verir; sunucu isteği tamamladığında, XMLHttpRequest nesnesinin içine ve özellikle
onreadystatechange özelliğine bakar. Daha sonra, bu özellikte belirlenen yöntem çağrılır.
Bu bir geri çağrıdır, çünkü sunucu Web sayfasına doğru bir geri çağrı başlatır -- bu, Web
sayfasının kendisinde olup bitenden bağımsızdır. Örneğin, sunucu bu yöntemi kullanıcı
sandalyesinde oturup, klavyesine dokunmazken çağırabilir; ancak, kullanıcı yazı yazarken,
faresini oynatırken, sayfayı aşağı kaydırırken, bir düğmeyi tıklatırken de bu yöntemi
çağırabilir ... kullanıcının ne yaptığının hiçbir önemi yoktur.

Burada devreye zamanuyumsuzluk girer: Kullanıcı formu bir düzeyde çalıştırırken, başka bir
düzeyde sunucu bir isteğe yanıt verir ve onreadystatechange özelliğinde belirtilen geri çağrı
yöntemini başlatır. Bu nedenle, bu yöntemi Liste 11'de gösterildiği şekilde, kodunuzda
belirtmeniz gerekir.

Liste 11. Bir geri çağrı yönteminin belirlenmesi


function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}

Bu özelliğin kodun neresinde ayarlandığına dikkat edin -- send() çağrılmadan önce ayarlanır.
Bu özelliği istek gönderilmeden önce ayarlamanız gerekir; böylece, sunucu isteğe yanıt
vermeyi tamamladığında özelliği arayabilir. Geriye, bu makalenin son bölümünde
odaklanacağımız updatePage() yönteminin kodlanması kalıyor.

Sunucu yanıtlarının işlenmesi

İsteğinizi gönderdiniz, kullanıcınız Web formunda mutlulukla çalışıyor (bu arada sunucu da
isteği işliyor) ve sunucu, isteği işlemeyi tamamlıyor. Sunucu onreadystatechange özelliğine
bakar ve çağrılacak yöntemi belirler. Bu gerçekleştikten sonra, zamanuyumsuz olsun ya da
olmasın uygulamanızı diğer uygulamalar gibi düşünebilirsiniz. Diğer bir deyişle, sunucuya
yanıt veren özel işlem yazma yöntemlerini uygulamanız gerekmez; yalnızca formu değiştirin,
kullanıcıyı başka bir URL'ye alın ya da sunucuya yanıt vermek için ne yapmanız gerekiyorsa
onu yapın. Bu bölümde, sunucuya yanıt verilmesi ve tipik bir işlemin yapılması -- kullanıcının
gördüğü formun değiştirilmesi -- üzerinde duracağız.

Geri çağrılar ve Ajax

Sunucunun işi bittiğinde ne yapması gerektiğini nasıl bildireceğinizi gördünüz:


XMLHttpRequest nesnesinin onreadystatechange özelliğini çalışacak işlevin adına

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 26/129


ayarlayın. Daha sonra, sunucu isteği işledikten sonra otomatik olarak bu işlevi çağırır. Bu
yöntemle ilgili parametreler hakkında kafa yormanıza da gerek yoktur. Liste 12'deki gibi basit
bir yöntemle işe başlayacaksınız.

Liste 12. Geri çağrı yönteminin kodlanması


<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}

if (!request)
alert("Error initializing XMLHttpRequest!");

function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}

function updatePage() {
alert("Server is done!");
}
</script>

Bu, sunucu işlemi tamamladığında, bunu size bildiren bir uyarı gönderir. Bu kodu kendi
sayfanızda deneyin, sayfayı kaydedin ve bir tarayıcıda açın (bu örnekte XHTML kullanmak
isterseniz, Liste 8'e bakın). Bir telefon numarası girip alandan çıktığınızda, uyarı iletisini
görmeniz gerekir (bkz. Şekil 3); ancak OK (Tamam) düğmesini tıklattığınızda uyarı defalarca
yeniden görüntülenir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 27/129


Şekil 3. Uyarı görüntüleyen Ajax kodu

Tarayıcınıza bağlı olarak, form uyarı görüntülemeyi durduruncaya kadar iki, üç, hatta dört
uyarı alırsınız. Peki neler oluyor? Anlaşılan istek/yanıt döngüsünün önemli bir bileşeni olan
HTTP hazır olma durumunu dikkate almadınız.

HTTP hazır olma durumları

Daha önce, sunucunun, isteği işlemesi bittiğinde XMLHttpRequest nesnesinin


onreadystatechange özelliğinden çağrılacak yöntemi aradığını söylemiştim. Bu doğru, ama
tüm gerçek bundan ibaret değil. Aslında sunucu, yöntemi HTTP hazırlık durumu her
değiştiğinde yeniden çağırır. Bu ne anlama geliyor? Öncelikle HTTP hazır olma durumlarını
(ready states) anlamanız gerekiyor.

HTTP hazır olma durumu, bir isteğin durumunu ya da durumlarını belirtir. İsteğin başlatılıp
başlatılmadığını, yanıtlanıp yanıtlanmadığını ya da istek/yanıt modelinin tamamlanıp
tamamlanmadığını anlatmak için kullanılır. Sunucunun sağladığı yanıt metninin ya da
verilerin okuma için güvenli olup olmadığını belirlemenize de yardımcı olur. Ajax
uygulamalarınızda beş hazır olma durumundan söz edebiliriz:

• 0: İstek başlatılmadı (open() çağrılmadan önce).


• 1: İstek hazırlandı, ancak henüz gönderilmedi (send() çağrılmadan önce).
• 2: İstek gönderildi ve işleniyor (bu noktada genellikle yanıtın içerik üstbilgilerini
alabilirsiniz).
• 3: İstek işleniyor; yanıttan bazı kısmi verileri alabilirsiniz, ancak sunucu yanıt vermeyi
tamamlamamıştır.
• 4: Yanıt tamamlandı; sunucunun yanıtını alabilir ve kullanabilirsiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 28/129


Tarayıcılar arası sorunların neredeyse tümünde, bu hazır olma durumları biraz tutarsız bir
şekilde kullanılmaktadır. Hazır olma durumlarının her zaman 0'dan 1'e, sonra 2'ye, 3'e ve en
son 4'e doğru gitmesini bekleyebilirsiniz, ama pratikte, bu çok ender görülen bir durumdur.
Bazı tarayıcılar hiçbir zaman 0 ya da 1 raporu vermez ve doğrudan 2, 3 ve 4'e atlar. Diğer
tarayıcılar tüm durumları raporlayabilir. Başka tarayıcılar da 1 durumunu birden çok defa
raporlayabilir. Son bölümde de gördüğünüz gibi, sunucu updatePage() yöntemini birkaç kez
çağırdı ve her bir çağrı, bir uyarı iletisinin görüntülenmesiyle sonuçlandı - büyük olasılıkla
sizin istediğiniz tam olarak bu değildi!

Ajax programlamasında, doğrudan ilgilenmeniz gereken tek durum 4 numaralı durumdur. Bu


durum, sunucu yanıtının tamamlandığını ve yanıt verilerini denetlemenin ve kullanmanın
güvenli olduğunu belirtir. Buna güvenmek için, geri çağrı yönteminizin ilk satırının Liste
13'teki gibi olması gerekir.

Liste 13. Hazır olma durumunu denetleme


function updatePage() {
if (request.readyState == 4)
alert("Server is done!");
}

Bu değişiklik, sunucunun gerçekten işlemi tamamlayıp tamamlamadığından emin olmak için


bir denetim gerçekleştirir. Ajax kodunun bu sürümünü çalıştırmayı denediğinizde, olması
gerektiği gibi yalnızca bir defa uyarı iletisi alırsınız.

HTTP durum kodları

Liste 13'teki kodun başarılı görünmesine rağmen, hâlâ bir sorunumuz var -- sunucu isteğinize
yanıt verip işlemi bitirir, ancak bir hata raporu verirse ne olacak? Unutmayın, Ajax, JSP,
kurallara uygun bir HTML formu ya da başka bir kod tipi tarafından çağrılıyorsa, bununla
sunucu tarafındaki kod ilgilenmelidir; sunucu tarafı kodunuz bilgileri raporlamak için
yalnızca geleneksel Web'e özel yöntemlere sahiptir. Web dünyasında, HTTP kodları bir
istekte ortaya çıkabilecek çeşitli sorunlarla ilgilenebilir.

Örneğin, bir URL için istek girdiniz, URL'yi yanlış yazdınız ve böyle bir sayfanın olmadığını
belirten bir 404 hata kodu aldınız. Bu, HTTP isteklerinin durum olarak alabileceği birçok
durum kodlarından yalnızca biridir (durum kodlarının tam listesine giden bir bağlantı için
Kaynaklar'a bakın). Güvenli ya da yasak verilere erişildiğini belirten 403 ve 401 hata kodları
da oldukça yaygındır. Bu durumların her birinde, bu kodlar tamamlanmış bir yanıtın
sonucudur. Diğer bir deyişle, sunucu isteği tamamlamıştır (HTTP hazır olma durumu 4'tür),
ancak istemcinin beklediği verileri döndürmüyor olabilir.

Daha sonra, hazır olma durumuna ek olarak HTTP durumunu da denetlemeniz gerekir. Her
şeyin tamam olduğunu belirten 200 durum kodunu arıyorsunuz. Hazır olma durumu 4 ve
durum kodu 200 olduğunda, sunucu verilerini işleyebilirsiniz ve bu veriler, tam olarak
istedikleriniz olmalıdır (bunlar bir hata ya da diğer sorun bildiren bilgi parçaları olmamalıdır).
Geri çağrı yönteminize Liste 14'te gösterilen başka bir durum denetimi ekleyin.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 29/129


Liste 14. HTTP durum kodunu denetleme
function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
}

Daha sağlam bir hata işleme özelliği eklemek için -- kodları çok karmaşıklaştırmadan -- diğer
durum kodları için bir ya da iki denetim ekleyebilirsiniz; Liste 15'teki değiştirilmiş
updatePage() örneğine bakın.

Liste 15. Birkaç küçük hata denetimi ekleme


function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
else if (request.status == 404)
alert("Request URL does not exist");
else
alert("Error: status code is " + request.status);
}

Şimdi getCustomerInfo() yöntemindeki URL'yi değiştirin ve var olmayan bir URL yazıp ne
olduğuna bakın. İstediğiniz URL'nin var olmadığını belirten bir uyarı görmelisiniz --
mükemmel! Bu, belki bütün hata koşullarını kapsamaz, ancak tipik bir Web uygulamasında
ortaya çıkabilecek sorunların yaklaşık %80'ini kapsayan basit bir değişikliktir.

Yanıt metninin okunması

İsteğinizin tam olarak işlendiğinden (hazır olma durumu yoluyla) ve sunucunun olağan,
olumlu bir yanıt verdiğinden (durum kodu yoluyla) emin olduğunuza göre, artık sunucudan
geri gönderilen verilerle uğraşabilirsiniz. Bu, uygun bir şekilde XMLHttpRequest nesnesinin
responseText özelliğinde saklanır.

responseText içindeki metnin biçim ya da uzunluk bakımından nasıl göründüğüne ilişkin


ayrıntılar özellikle belirsiz bırakılmıştır. Bu, sunucunun bu metni hemen her şeye
ayarlayabilmesini sağlar. Örneğin, bir komut dosyası birbirinden virgülle ayrılmış değerler
döndürürken, bir diğeri birbirinden dikey çubukla ayrılmış (dikey çubuk | karakteridir)
değerler, bir başkası da uzun bir metin dizisi döndürebilir. Hepsi de sunucuya bağlıdır.

Bu makalede kullanılan örnekte, sunucu müşterinin son siparişini ve adresini, dikey çubukla
birbirinden ayrılmış bir şekilde döndürür. Sipariş ve adres, form üzerindeki öğelerin
değerlerini ayarlamak için kullanılır; Liste 16'da görüntüyü güncelleyen kod gösterilmektedir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 30/129


Liste 16. Sunucunun yanıtını işleme
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "
");
} else
alert("status is " + request.status);
}
}

Önce, responseText çekilir ve JavaScript split() yöntemi kullanılarak dikey çubuk


simgesiyle ayrılır. Ortaya çıkan değer dizisi response içine aktarılır. İlk değere (müşterinin
son siparişi) dizide response[0] olarak erişilir ve "order" (sipariş) tanıtıcısının bulunduğu
alanın değeri olarak ayarlanır. Dizideki ikinci değer olan response[1], müşterinin adresidir
ve daha az işlem gerektirir. Adres satırları birbirinden normal satır ayıcılarla ("\n" karakteri)
ayrıldığı için, kodun bunları XHTML stilindeki satır ayırıcılarla (<br />) değiştirmesi
gerekir. Bu, uygun bir ifade ile replace() işlevinin kullanılmasıyla gerçekleştirilir. Son
olarak, değiştirilen metin HTML formunda div parametresinin iç HTML'i olarak ayarlanır.
Sonuçta form, Şekil 4'teki gibi birden bire müşterinin bilgileriyle güncellenir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 31/129


Şekil 4. Müşteri verileri alındıktan sonra Break Neck formu

Toparlamadan önce, XMLHttpRequest nesnesinin responseXML adı verilen başka bir önemli
özelliğinden söz etmek istiyorum. Bu özellik, sunucunun XML ile yanıt vermesi durumunda
bir XML yanıtını içerir (tahmin edebilir miydiniz?). Bir XML yanıtıyla çalışma, düz metinle
çalışmaktan biraz daha farklıdır ve ayrıştırma, DOM (Document Object Model; Belge Nesne
Modeli) ve diğer bazı konuları da içerir. Sonraki bir makalede XML ile ilgili ayrıntılı bilgi
verilecektir. Yine de responseXML özelliği responseText çevresinde toplanan tartışmalarla
geldiği için burada sözü edilebilir. Birçok basit Ajax uygulamasında, tek ihtiyacınız olan
responseText özelliğidir, ancak yakında Ajax uygulamalarında XML ile çalışmayı da
öğreneceksiniz.

Sonuç

XMLHttpRequest nesnesinden biraz sıkılmış olabilirsiniz -- tek bir nesneyle ilgili bir
makalenin tamamını, özellikle de nesne bu kadar basitse, genellikle okumam. Ancak, bu
nesneyi yazdığınız ve Ajax kullanan her sayfada ve uygulamada defalarca kullanacaksınız.
Doğruyu söylemek gerekirse, hâlâ XMLHttpRequest nesnesiyle ilgili anlatılacak birkaç şey
var. Sonraki makalelerde, isteklerinizde GET ile birlikte POST kullanımını, sunucudan gelen
yanıtın yanı sıra isteğinizde içerik üstbilgileri belirleme ve okumayı da öğreneceksiniz;
isteklerinizi nasıl kodlamanız gerektiğini ve istek/yanıt modelinizde XML'lerin nasıl
işleneceğini anlayacaksınız.

Ayrıca, sık kullanılan Ajax araç takımlarından bazılarını da göreceksiniz. Bu araç takımları
aslında bu makalede anlatılan ayrıntıların çoğunu aydınlatır ve Ajax programlamasını

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 32/129


kolaylaştırır. Araç takımları bu kadar hazır elinizin altındayken, tüm bu düşük düzeyli
ayrıntıları neden kodlamanız gerektiğini merak edebilirsiniz. Bunun yanıtı, uygulamanızda
neyin çalıştığını bilmezseniz, neyin yanlış gittiğini de bilemeyeceğiniz olacaktır.

Bu nedenle, bu ayrıntıları atlamayın ya da hızlı geçmeyin; böylece elinizin altındaki hazır araç
takımında bir hata oluştuğunda, kafanızı kaşıyıp destek için e-posta göndermenize gerek
kalmaz. XMLHttpRequest nesnesinin doğrudan nasıl kullanılacağını anladığınızda, en garip
sorunlarda hata ayıklamak, hatta sorunu düzeltmek sizin için çok kolay olacaktır. Araç
takımları, tüm sorunlarınızla onların ilgilenmelerine güvenmediğiniz sürece yararlıdır.

Öyleyse, XMLHttpRequest nesnesini iyice tanıyın. Aslında, bir araç takımı kullanan çalışan
bir Ajax kodunuz varsa, bu kodu yalnızca XMLHttpRequest nesnesiyle, ve bunun özellikleri
ve yöntemleriyle yeniden yazmayı deneyin. Bu sizin için iyi bir alıştırma olacaktır ve neler
olup bittiğini çok daha iyi anlamanızı sağlayacaktır.

Sonraki makalede, bu nesneyle ilgili daha derin konulara gireceğiz, POST isteklerinin nasıl
kullanılacağını ve birkaç farklı biçimde veri göndermeyi öğrenmenin yanı sıra bu nesnenin
daha becerikli özelliklerini (responseXML gibi) keşfedeceğiz. Bu nedenle şimdi kodlamaya
başlayın ve bir ay kadar sonra buraya yeniden göz atın.

Kaynaklar

Bilgi Edinme

• Mastering Ajax: Introduction to Ajax (Ajax Konusunda Uzmanlaşma: Ajax'a Giriş)


(developerWorks, Aralık 2005), Web siteleri oluşturmak için verimli bir yaklaşım olan
Ajax'ı anlamanızı sağlar. (Bu makalenin kaynak listesi, tek başına ziyaret etmeye
değer!)

• "Use Ajax with WebSphere Portal" (Ajax'ın WebSphere Portal ile kullanılması)
(developerWorks, Haziran 2006), portal performansını artırmak, daha temiz bir portal
uygulaması mimarisi ve -- en önemlisi -- kullanıcılarınıza çok daha hızlı yanıt veren
bir portal yaratmak için.

• Building Dynamic Java Applications (Dinamik Java Uygulamalarının Oluşturulması)


(developerWorks, Eylül 2005), Java bakış açısıyla Ajax'a sunucu tarafından bir bakış.

• Java object serialization for Ajax (Ajax için Java nesnesi diziselleştirmesi)
(developerWorks, Ekim 2005), ağ üzerinden nesne gönderme ve Ajax ile etkileşimde
bulunma konularını Java bakış açısıyla inceler.

• Call SOAP Web services with Ajax (Ajax ile SOAP Web hizmetlerinin çağrılması)
(developerWorks, Ekim 2005), Ajax'ı var olan SOAP tabanlı Web hizmetleriyle
bütünleştirme üzerine yazılmış ileri düzey bir makaledir.

• Google GMail, Web'in çalışma şeklini değiştiren, Ajax tabanlı uygulamalara harika bir
örnektir.

• Google Maps, başka bir Google tabanlı Web 2.0 uygulamasıdır.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 33/129


• Flickr, Web tabanlı bir uygulama için masaüstü görünümü oluşturmak için Ajax'ın
kullanıldığı harika bir örnektir.

• Ajax: A New Approach to Web Applications (Ajax: Web Uygulamalarına Yeni Bir
Yaklaşım), Ajax moniker teriminin ilk kez kullanıldığı ve tüm Ajax geliştiricilerinin
okuması gereken bir makaledir.

• Why Ajax Matters Now (Ajax Neden Bu Kadar Önemli), Ajax'ın (şimdi) neden bu
kadar önemli olduğunu anlamanıza yardımcı olacaktır.

• Microsoft'un tarayıcısı olan Internet Explorer'ı kullanıyorsanız, Microsoft Developer


Network's XML Developer Center (Microsoft Geliştirici Ağı XML Geliştirme
Merkezi) olanağından haberleri alabilirsiniz.

• Microsoft XML ayrıştırıcısıyla (MSXML) ilgili ek bilgiye çevrimiçi belgelerden


ulaşın.

• Bir yanıtın içerebileceği tüm HTTP durum kodlarını içeren bu listeye göz atın.

• DeveloperWorks Web Mimarisi alanı, çeşitli Web tabanlı çözümleri kapsayan


makaleleri içerir.

Ürün ve teknoloji edinme

• Head Rush Ajax, Elisabeth Freeman, Eric Freeman ve Brett McLaughlin (Şubat 2006,
O'Reilly Media, Inc.), bu makaledeki düşünceleri alır ve Head First stilinde beyninize
yükler.

• Java and XML, İkinci Basım, Brett McLaughlin (Ağustos 2001, O'Reilly Media, Inc.),
yazarın XHTML ve XML dönüşümleriyle ilgili görüşlerini içerir.

• JavaScript: The Definitive Guide, David Flanagan (Kasım 2001, O'Reilly Media,
Inc.), JavaScript, dinamik Web sayfalarıyla çalışmayla ilgili kapsamlı yönergeler içerir
ve sonraki basımda Ajax ile ilgili iki yeni bölüm bulunur.

• Head First HTML with CSS & XHTML, Elizabeth ve Eric Freeman (Aralık 2005,
O'Reilly Media, Inc.), XHTML, CSS ve bu ikisinin nasıl birlikte kullanılacağını
öğrenmeyle ilgili eksiksiz bir kaynaktır.

Tartışma

• Tartışma forumuna katılın.

• developerWorks Web günlükleri: DeveloperWorks topluluğuna katılın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 34/129


Ajax Konusunda Uzmanlaşma, Bölüm 3:
Ajax'ta gelişmiş istekler ve yanıtlar
HTTP durum kodlarını, hazır olma durumlarını ve XMLHttpRequest nesnesini tam olarak
anlayın

Düzey: Başlangıç

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

14 Şubat 2006

Çoğu Web geliştiricisi için basit istekler oluşturmak ve basit yanıtlar almak yeterlidir, ancak
Ajax konusunda uzmanlaşmak isteyen geliştiriciler için HTTP durum kodlarının, hazır olma
durumlarının ve XMLHttpRequest nesnesinin tam olarak anlaşılması gerekir. Bu makalede
Brett McLaughlin, size farklı durum kodlarını gösterecek, tarayıcıların her bir durum kodunu
nasıl işlediğini anlatacak ve Ajax ile yapabileceğiniz, daha az kullanılan HTTP isteklerine
ilişkin örnekler verecek.

Bu dizinin son makalesinde, sunucu tarafındaki uygulamaya ya da komut dosyasında


gönderilen istekleri işleyen ve sunucu tarafındaki bileşenden gelen verileri de işleyen, Ajax
uygulamasının ana parçası olan XMLHttpRequest nesnesine sağlam bir giriş yapmıştık. Ajax
uygulamalarının tümü XMLHttpRequest nesnesini kullanır, bu nedenle Ajax
uygulamalarınızın daha iyi çalışması için bu nesneyi çok iyi bilmek isteyeceksiniz.

Bu makalede, son makalemde anlattığım temel konuların biraz ötesine geçip bu istek
nesnesinin üç anahtar parçasıyla ilgili daha ayrıntılı bilgi vereceğim:

• HTTP hazır olma durumu


• HTTP durum kodu
• Gerçekleştirebileceğiniz istek tipleri

Bunların her biri genellikle isteklerin altyapı parçaları olarak görülür; sonuç olarak, bu
konularla ilgili çok az ayrıntılı bilgi bulabilirsiniz. Ancak, Ajax programlamasıyla amatörce
bir uğraştan daha çok şey yapmak istiyorsanız, hazır olma durumları, durum kodları ve
istekler konusunda oldukça iyi olmanız gerekir. Uygulamanızda bir şeyler ters gittiğinde -- ki
her zaman bir şeyler ters gider -- hazır olma durumlarını anlamak, HEAD isteklerini nasıl
yapacağınızı ya da 400 durum kodunun anlamını bilmek, beş dakikalık bir hata ayıklama
işlemiyle beş saatlik boşa uğraş ve kargaşa arasındaki farkı oluşturabilir.

XMLHttpRequest ya da XMLHttp:
Farklı adlı bir gül

Microsoft™ ve Internet Explorer, Mozilla,


Opera, Safari ve Microsoft dışındaki çoğu

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 35/129


tarayıcının kullandığı XMLHttpRequest
nesnesi yerine XMLHttp adlı bir nesne
kullanır. Basit olması adına, bu iki nesne
tipinden de XMLHttpRequest olarak söz
edeceğim. Bu, tüm Web üzerindeki yaygın
uygulamayla eşleşir ve Microsoft'un
XMLHttpRequest adını Internet Explorer
7.0'daki istek nesnesinin adı olarak
kullanma amacına da uygundur. (Bu
konuda ek bilgi edinmek için yeniden
Bölüm 2'ye bakın.)

Önce HTTP hazır olma durumlarına bakacağım.

HTTP hazır olma durumlarının ayrıntıları

Son makaleden, XMLHttpRequest nesnesinin readyState adlı bir özelliğinin olduğunu


hatırlarsınız. Bu özellik, sunucunun bir isteği tamamladığından emin olmanızı sağlar ve
genellikle, bir geri çağrı işlevi, sunucudan alınan verileri bir Web formunu ya da sayfasını
güncellemek için kullanır. Liste 1'de bunun basit bir örneği gösterilmektedir (bu serinin son
makalesinde de görebilirsiniz -- bkz. Kaynaklar).

Liste 1. Geri çağrı işlevinde bir sunucunun yanıtıyla çalışma


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
} else
alert("status is " + request.status);
}
}

Hazır olma durumlarının en yaygın (ve en basit) kullanımı kesinlikle budur. "4" rakamından
da tahmin edebileceğiniz gibi birkaç tane hazır olma durumu söz konusudur (bu listeyi son
makalede de görebilirsiniz -- bkz. Kaynaklar):

• 0: İstek başlatılmadı (open() çağrılmadan önce).


• 1: İstek ayarlandı, ancak henüz gönderilmedi (send() çağrılmadan önce).
• 2: İstek gönderildi ve işleniyor (bu noktada genellikle yanıtın içerik üstbilgilerini
alabilirsiniz).
• 3: İstek işleniyor; yanıttan bazı kısmi verileri alabilirsiniz, ancak sunucu yanıt vermeyi
tamamlamamıştır.
• 4: Yanıt tamamlandı; sunucunun yanıtını alabilir ve kullanabilirsiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 36/129


Ajax programlamasının temel unsurlarının ötesine geçmek istiyorsanız, yalnızca bu durumları
bilmeniz yeterli değildir, ne zaman ortaya çıktıklarını ve bunları nasıl kullanabileceğinizi de
bilmeniz gerekir. Birincisi ve en önemlisi, her bir hazır olma durumunda, bir isteğin hangi
durumunda karşılaşacağınızı öğrenmelisiniz. Ne yazık ki, kolay anlaşılır bir şey değildir ve
birkaç özel durumu da içerir.

Gizli hazır olma durumları

readyState özelliği 0 (readyState == 0) ile gösterilen birinci hazırolma durumu,


başlatılmamış bir isteği belirtir. İstek nesnenizde open() işlevini çağırır çağırmaz, bu özellik
1 değerini alır. Hemen hemen her zaman isteğinizi başlattığınızda open() işlevini çağırdığınız
için readyState == 0 değerinin görülmesi çok nadiren olay bir şeydir. Ayrıca, başlatılmamış
hazır olma durumu, pratik uygulamalarda kullanışsız bir bilgidir.

Yine de eksiksiz bilgi verebilmek açısından, Liste 2'de hazır olma durumunun nasıl 0 değerine
ayarlanacağı gösterilmektedir.

Liste 2. 0 hazır durumunun alınması


function getSalesData() {
// Create a request object
createRequest();
alert("Ready state is: " + request.readyState);

// Setup (initialize) the request


var url = "/boards/servlet/UpdateBoardSales";
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}

Bu basit örnekte, Web sayfanız bir isteği başlatmak için getSalesData() işlevini çağırır
(örneğin bir düğme tıklatıldığında). Hazır olma durumunu open() çağrılmadan önce
denetlemeniz gerektiğini unutmayın. Şekil 1'de bu uygulamanın çalışma sonucu
gösterilmektedir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 37/129


Şekil 1. 0 hazır olma durumu

0 ne zaman 4'e eşittir

Birden çok JavaScript işlevinin aynı istek


nesnesini kullandığı durumlarda, istek
nesnesinin kullanılmadığından emin olmak
için 0 hazır olma durumunun aranması bazı
sorunlara neden olabilir. Tamamlanmış bir
istek readyState == 4 ile
bildirildiğinden, sık sık, kullanılmayan
istek nesnelerinin hala 4 numaralı hazır
olma durumunda kaldığını göreceksiniz --
sunucudan gelen veriler kullanılmıştır,
ancak hazır olma durumu ilk durumuna
getirmek için o zamandan beri hiçbir işlem
yapılmamıştır. İstek nesnesini ilk
durumuna getiren abort() adlı bir işlev
vardır, ancak asıl olarak bu amaç için
tasarlanmamıştır. Birden çok işlev
kullanmanız gerekiyorsa, nesneyi birden
çok işlev arasında paylaşmak yerine her bir
işlev için bir istek nesnesi yaratmanız ve
kullanmanız daha iyi olabilir.

Açıkçası, bunun size fazla bir yararı olmaz; çoğu zaman open() işlevinin çağrılmadığından
emin olmak isteyeceğiniz durumlar ender görülür. Neredeyse gerçek dünyaya benzeyen Ajax
programlamasında bu hazır olma durumu, yalnızca birden çok işlevde aynı XMLHttpRequest
nesnesini kullanarak birden çok istekte bulunulursa kullanılır. Bu durumda (çok nadiren de
olsa), yeni isteklerde bulunmadan önce bir istek nesnesinin başlatılmamış durumda
(readyState == 0) olduğundan emin olmak isteyebilirsiniz. Bu esas olarak, başka bir işlevin
nesneyi aynı anda kullanmamasını sağlar.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 38/129


Devam eden isteğin hazır olma durumunun görüntülenmesi

0 hazır olma durumunun dışında, istek nesnenizin tipik bir istek ve yanıt sürecinde diğer hazır
olma durumlarının her birinden geçmesi ve son olarak 4 numaralı hazır olma durumunda
işlemi bitirmesi gerekir. İşte bu noktada, çoğu geri çağrı işlevinde gördüğünüz if
(request.readyState == 4) satırı devreye girer; sunucunun işlemi tamamladığından ve
Web sayfasını güncellemenin ya da sunucudan alınan verilere dayalı bir işlem yapmanın
güvenli olduğundan emin olmanızı sağlar.

Gerçekleşirken bu işlemi gerçekten görmek önemsiz bir görevdir. Hazır olma durumu 4
değerindeyse, geri çağrınızda yalnızca kodu çalıştırmak yerine, geri çağrınızın her çağrılışında
hazır olma durumunu çıkarın. Bunu yapan koda ilişkin bir örnek görmek için Liste 3'e bakın.

Liste 3. Hazır olma durumunun denetlenmesi


function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " +
request.readyState);
}

Bunu nasıl çalıştıracağınızdan tam olarak emin değilseniz, Web sayfanızdan çağrılacak bir
işlev yaratmanız ve bunun, sunucu tarafındaki bileşene bir istek göndermesini sağlamanız
gerekir (böyle bir işlev Liste 2'de ve bu dizinin birinci ve ikinci makalesindeki örneklerde
gösterilmiştir). İsteğinizi oluştururken, geri çağrı işlevini updatePage() işlevine
ayarlamadığınızdan emin olun; bunu yapmak için istek nesnenizin onreadystatechange
özelliğini updatePage() işlevine ayarlayın.

Bu kod, onreadystatechange özelliğinin tam olarak ne anlama geldiğini gösteren güzel bir
örnektir -- isteğin hazır olma durumunun her değişmesinde, updatePage() çağrılır ve bir
uyarı görüntülenir. Şekil 2'de, 1 hazır olma durumunda çağrılan bu işlevin bir örneği
gösterilmektedir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 39/129


Şekil 2. 1 hazır olma durumu

Bu kodu kendiniz deneyin. Kodu Web sayfanıza koyun ve olay işleyicinizi etkinleştirin (bir
düğmeyi tıklatın, bir alandan çıkın ya da bir isteği tetiklemek üzere hazırladığınız herhangi bir
yöntemi kullanın). İsteğinizin hazır olma durumu her değiştiğinde, çağrı işleviniz birkaç kez
çalışır ve her bir hazır olma durumu için bir uyarı görüntülenir. Bir isteğin aşamalarını
izlemek için en iyi yöntem budur.

Tarayıcı tutarsızlıkları

Bu işlemin temel mantığını kavradıktan sonra, Web sayfanıza farklı tarayıcılardan erişmeyi
deneyin. Bu hazır olma durumlarının işlenmesiyle ilgili bazı tutarsızlıkları fark etmeniz
gerekir. Örneğin, Firefox 1.5'te aşağıdaki hazır olma durumlarını görürsünüz:

• 1
• 2
• 3
• 4

Burada her bir istek aşaması gösterildiği için bu sizi şaşırtmamalıdır. Ancak, aynı uygulamaya
Safari üzerinden erişirseniz, ilginç bir şeyle karşılaşırsınız -- daha doğrusu karşılaşmazsınız.
Safari 2.0.1'de göreceğiniz durumlar şunlardır:

• 2
• 3
• 4

Safari, birinci hazır olma durumunu dışarıda bırakır ve bunun anlamlı bir açıklaması yoktur;
Safari'nin çalışma yöntemi böyledir. Bu önemli bir noktayı da gösterir: Sunucudan alınan
verileri kullanmadan önce isteğin 4 numaralı hazır olma durumunda olup olmadığından emin
olmak iyi bir fikir olsa da, her bir geçici hazır olma durumuna dayalı kod yazma farklı
tarayıcılarda farklı sonuçlar almanızı sağlar.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 40/129


Örneğin, Opera 8.5 kullanırken işler, görüntülenen hazır olma durumları açısından daha da
kötüdür:

• 3
• 4

Son olarak, Internet Explorer aşağıdaki durumlarla yanıt verir:

• 1
• 2
• 3
• 4

Bir istekle ilgili sorun yaşıyorsanız, sorunları aramanız gereken ilk yer burası olmalıdır.
Kodun düzgün çalıştığından emin olabilmeniz için isteğin hazır olma durumunu size
gösterecek bir uyarı ekleyin. Kodunuzu Internet Explorer ve Firefox üzerinde deneyin -- dört
hazır olma durumunu da alabilecek ve isteğin her bir aşamasını denetleyebileceksiniz.

Bir sonraki adım olarak yanıt tarafına bakacağım.

Mikroskop altındaki yanıt verileri

Bir istek sırasında ortaya çıkan çeşitli hazır olma durumlarını anladıktan sonra,
XMLHttpRequest nesnesinin başka bir önemli parçasına bakmak için hazırsınız; bu,
responseText özelliğidir. Son makaleden de hatırlayacağınız gibi bu, sunucudan verileri
almak için kullanılan özelliktir. Sunucu bir isteği işlemeyi tamamladığında, isteğe yanıt
vermek için gereken verileri isteğin responseText kısmına yerleştirir. Daha sonra, Liste 1 ve
Liste 4'te görülebileceği gibi geri çağrı işleviniz bu verileri kullanabilir.

Liste 4. Sunucudan gelen yanıtın kullanılması


function updatePage() {
if (request.readyState == 4) {
var newTotal = request.responseText;
var totalSoldEl = document.getElementById("total-sold");
var netProfitEl = document.getElementById("net-profit");
replaceText(totalSoldEl, newTotal);

/* Figure out the new net profit */


var boardCostEl = document.getElementById("board-cost");
var boardCost = getText(boardCostEl);
var manCostEl = document.getElementById("man-cost");
var manCost = getText(manCostEl);
var profitPerBoard = boardCost - manCost;
var netProfit = profitPerBoard * newTotal;

/* Update the net profit on the sales form */


netProfit = Math.round(netProfit * 100) / 100;
replaceText(netProfitEl, netProfit);
}

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 41/129


Liste 1 oldukça basittir; Liste 4 biraz daha karmaşık gelebilir, ancak başlangıç olarak, her
ikisinin de hazır olma durumunu denetlediğini ve responseText özelliğindeki değeri (ya da
değerleri) aldığını söyleyebiliriz.

İstek sırasında yanıt metninin görüntülenmesi

Hazır olma durumu gibi, responseText özelliğinin değeri isteğin yaşam döngüsü içinde
değişir. Bunu gerçekleşirken görmek için isteğin hazır olma durumunun yanı sıra yanıt
metnini de sınayan Liste 5'te gösterilene benzer bir kod kullanın.

Liste 5. ResponseText özelliğinin sınanması


function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " + request.readyState
+
" and a response text of '" + request.responseText + "'");
}

Web uygulamanızı bir tarayıcıda açın ve isteğinizi etkinleştirin. Bu koddan alabileceğinizin


en fazlasını almak için, Firefox ya da Internet Explorer kullanın. Bu iki tarayıcı bir istek
sırasında olası tüm hazır olma durumlarını bildirir. Örneğin, 2 numaralı hazır olma
durumunda responseText özelliği tanımlı değildir (bkz. Şekil 3); JavaScript konsolu da
açıksa bir hata iletisi görüntülenebilir.

Şekil 3. 2 numaralı hazır olma durumundaki yanıt metni

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 42/129


Ancak 3 numaralı hazır olma durumunda, sunucu responseText özelliğine, en azından bu
örnekte bir değer yerleştirir (bkz. Şekil 4).

Şekil 4. 3 numaralı hazır olma durumundaki yanıt metni

3 numaralı hazır olma durumundaki yanıtlarınızın, komut dosyaları, sunucular ve tarayıcılar


arasında farklılık gösterdiğini göreceksiniz. Yine de bu, uygulamanızda hata ayıklarken
inanılmaz derecede yardımcı olur.

Güvenli verilerin alınması

Tüm belgeler ve belirtimler, yalnızca 4 numaralı hazır olma durumunda verilerin kullanım
açısından güvenli olduğu konusunda ısrarlıdır. İnanın bana, responseText özelliği 3
numaralı hazır olma durumundayken verilerin alınamayacağı durumlar çok azdır. Ancak,
uygulamanızda buna güvenmek kötü bir fikirdir -- 3 numaralı hazır olma durumundaki
tamamlanmış verilere dayalı bir kod yazdığınızda, verilerin tamamlanmamış olması neredeyse
kesindir.

3 numaralı hazır olma durumunda kullanıcıya, bir yanıtın gelmek üzere olduğu belirten bir
geri bildirim sağlamak daha iyi bir fikirdir. alert() gibi bir işlev kullanmak kötü bir fikirdir -
- Ajax kullanmak ve daha sonra, kullanıcıyı bir uyarı iletişim kutusuyla engellemek çok da
mantıklı değildir -- bunun yerine formunuzdaki ya da sayfanızdaki bir alanı hazır olma
durumu değiştikçe güncelleyebilirsiniz. Örneğin, 1 numaralı hazır olma durumu için bir
aşama göstergesinin %25'lik, 2 numaralı hazır olma durumu için %50'lik, 3 numaralı hazır
olma durumu için %75'lik ve 4 numaralı hazır olma durumu için %100'lük (tamamlanmış)
kısmına ilerleyen bir görünüm hazırlamayı deneyin.

Gördüğünüz gibi bu yaklaşım akıllıca, ancak tarayıcıya bağlı olacaktır. Örneğin Opera'da ilk
iki hazır olma durumunu hiç almazsınız ya da Safari'de birinci durum (1) atlanır. Bu nedenle,
bu makaleye dahil etmek yerine kodu bu haliyle burada, bir alıştırma olarak bırakacağım.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 43/129


Durum kodlarına bakma zamanı.

HTTP durum kodlarına yakından bakış

Hazır olma durumlarını ve sunucunun yanıtını, Ajax programlama teknikleri çantanıza


koydunuzda, Ajax uygulamalarıyla ilgili başka bir geliştirme düzeyine -- HTTP durum
kodlarıyla çalışma -- geçmeye hazır olursunuz. Bu kodlar, Ajax için yeni kavramlar değildir.
Bunlar, Web'in ortaya çıkışından bu yana var olan kavramlardır. Büyük olasılıkla Web
tarayıcınızda bunlardan birkaçını görmüşsünüzdür:

• 401: Yetkisiz
• 403: Yasak
• 404: Bulunamadı

Ek kodları da bulabilirsiniz (tam liste için bkz. Kaynaklar). Ajax uygulamalarınıza başka bir
denetim ve yanıt verebilirlik düzeyi (ve özellikle daha güçlü hata işleme özelliği) eklemek
için bir istekteki ve yanıttaki durum kodlarını doğru biçimde denetlemeniz gerekir.

200: Her şey yolunda

Birçok Ajax uygulamasında, Liste 6'daki gibi hazır olma durumunu denetleyen ve daha sonra,
sunucu yanıtındaki verilerle çalışmaya devam eden bir geri çağrı işlevi görürsünüz.

Liste 6. Durum kodunu yoksayan geri çağrı işlevi


function updatePage() {
if (request.readyState == 4) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
}
}

Bu, Ajax programlaması için dar görüşlü ve hataya eğilimli bir yaklaşımdır. Bir komut
dosyası, kimlik doğrulaması gerektirirse ve isteğiniz geçerli kimlik bilgilerini sağlayamazsa,
sunucu 403 ya da 401 gibi bir hata kodu döndürür. Ancak, sunucu isteğe yanıt verdiği için
hazır olma durumu 4 değerine gelir (istediğiniz ya da istek için beklediğiniz yanıtı
alamayabilirsiniz). Sonuç olarak, kullanıcı geçerli verileri alamaz ve JavaScript var olmayan
sunucu verilerini kullanmayı denediğinde kötü bir hata bile alabilir.

Sunucunun istekle ilgili işlemi bitirdiğinden ve "Her şey yolunda" durum kodunu
gönderdiğinden emin olmak için çok az bir çaba göstermeniz yeterli olacaktır. Bu kod
"200"'dür ve XMLHttpRequest nesnesinin status özelliğiyle birlikte raporlanır. Sunucunun
yalnızca istekle işini bitirdiğinden değil, aynı zamanda olumlu bir durum da bildirdiğinden
emin olmak için geri çağrı işlevinize Liste 7'de gösterilen denetimi ekleyin.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 44/129


Liste 7. Geçerli durum kodunun denetlenmesi
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
} else
alert("status is " + request.status);
}
}

Birkaç satırlık kod eklemesiyle, bir şeyler yanlış giderse, kullanıcıların, herhangi bir
açıklaması olmayan karışık verilerin bulunduğu bir sayfa yerine (şüpheli de olsa) yararlı bir
hata iletisi alacaklarından emin olabilirsiniz.

Yeniden yöneltme ya da yeniden yönlendirme

Hatalarla ilgili konunun derinliklerine dalmadan önce, Ajax kullanırken endişelenmenizi


gerektirmeyecek bir şeyden söz edebiliriz -- yeniden yöneltmeler. HTTP durum kodlarında
bunlar, 300 durum kodu ailesiyle bildirilir:

• 301: Kalıcı olarak taşındı


• 302: Bulunamadı (istek başka bir URL/URI'ya yeniden yöneltildi)
• 305: Yedek Sunucu Kullanın (isteğin, istekte bulunulan kaynağa erişebilmesi için bir
yedek sunucu kullanması gerekir)

Ajax programcıları iki nedenle yeniden yöneltmeler konusunda endişelenmezler:

• Birincisi, Ajax uygulamaları neredeyse her zaman özel bir sunucu tarafı komut
dosyası, sunucu uygulaması ya da uygulama için yazılır. Bu bileşenin Ajax
programcısının haberi olmadan ortadan kaybolması ve başka bir yere taşınması çok
ender görülen bir olaydır. Genellikle bir kaynağın taşındığını (kendiniz taşıdığınız ya
da taşıttığınız için) bildiğinizden, isteğinizdeki URL'yi değiştirir ve hiçbir zaman bu
tür bir sonuçla karşılaşmazsınız.
• Konu ile daha ilgili bir neden de Ajax uygulamalarının ve isteklerin kum havuzu
yöntemini kullanmasıdır. Bu, Ajax isteklerinin gönderildiği Web sayfasına hizmet
veren etki alanının, bu isteklere yanıt vermesi gereken etki alanı olduğu anlamına
gelir. Bu nedenle, ebay.com etki alanından hizmet alan bir Web sayfası, amazon.com
üzerinde çalışan bir komut dosyasına Ajax stili bir istekte bulunamaz; ibm.com
üzerindeki Ajax uygulamaları netbeans.org üzerinde çalışan sunucu uygulamalarına
isteklerde bulunamaz.

Sonuç olarak, istekleriniz, bir güvenlik hatası oluşturulmadan başka bir sunucuya yeniden
yöneltilemez. Böyle durumlarda, hiçbir durum kodu alamazsınız. Genellikle hata ayıklama
konsolunda bir JavaScript hatası bulunur. Birçok durum kodu üzerinde düşünürken, yeniden
yöneltme kodlarının tamamını göz ardı edebilirsiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 45/129


Uç durumlar ve zor durumlar

Bu noktada, yeni programcılar bütün bu


yaygaranın neyle ilgili olduğunu merak
ediyor olabilir. 2 ve 3 gibi hazır olma
durumlarıyla ve 403 gibi durum kodlarıyla
çalışmayı gerektiren Ajax isteklerinin
toplam Ajax isteklerinin %5'inden daha az
olduğu doğrudur (ve aslında, bu oran %1
ve altına daha yakın olabilir). Bu durumlar
önemlidir ve uç durumlar olarak
adlandırılır -- en garip koşulların yerine
getirildiği en alışılmadık durumlar.
Alışılmadık olsalar da, uç durumlar
kullanıcıların çoğunu öfkelendiren
olayların %80'ini oluşturur!

Tipik bir kullanıcı bir uygulamanın 100


defa düzgün çalışmasını unutur, ama
çalışmadığı bir defayı kesinlikle hatırlar.
Uç durumlarla -- ve zor durumlarla --
düzgün bir şekilde başa çıkabilirseniz, size
güvenen kullanıcılar sitenize geri döner.

Hatalar

200 durum koduyla ilgilendikten ve 300 durum kodu ailesini büyük oranda dikkate
almayabileceğinizi fark ettikten sonra, endişelenmeniz gereken diğer tek kod grubu 400
ailesidir. Bunlar, çeşitli hata tiplerini belirtir. Liste 7'ye bakın ve hatalar işlenirken, kullanıcıya
yalnızca çok soysal bir hata iletisinin bildirildiğine dikkat edin. Bu, doğru yönde bir adım olsa
da kullanıcıya ya da uygulama üzerinde çalışan bir programcıya aslında neyin yanlış gittiğini
açıklama açısından biraz yararsız bir iletidir.

Öncelikle, eksik sayfalar için destek ekleyin. Bu durumla, üretim sistemlerinde gerçekten de
sık karşılaşılmaz, ancak sınama amacıyla komut dosyasının taşınması ya da bir programcının
yanlış bir URL girmesi yaygın bir uygulamadır. 404 hatalarını güzel bir şekilde
raporlayabilirseniz, kafası karışan kullanıcılara ve programcılara yardım etmek için çok daha
fazlasını sağlayabilirsiniz. Örneğin, sunucu üzerindeki bir komut dosyası kaldırıldıysa ve
Liste 7'deki kodu kullanırsanız, Şekil 5'tekine benzer tanımsız bir hata görürsünüz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 46/129


Şekil 5. Soysal hataların işlenmesi

Kullanıcı, sorunun kimlik doğrulamasından mı, eksik bir komut dosyasından mı (buradaki
neden budur), kullanıcı hatasından mı, yoksa kod içindeki bir hatadan mı kaynaklandığını
anlayamaz. Bazı basit kod eklemeleri, bu hatanın çok daha kesin olmasını sağlayabilir. Kimlik
doğrulama hatalarının yanı sıra eksik komut dosyalarını kesin bir iletiyle işleyen Liste 8'e
bakın.

Liste 8. Geçerli durum kodunun denetlenmesi


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "<br />");
} else if (request.status == 404) {
alert ("Requested URL is not found.");
} else if (request.status == 403) {
alert("Access denied.");
} else
alert("status is " + request.status);
}
}

Bu kod hâlâ çok basittir, ancak bazı ek bilgiler de sağlar. Şekil 6'da,Şekil 5'teki hatanın aynısı
gösterilmektedir, ancak bu defa, hata işleme kodu kullanıcıya ya da programcıya ne olduğu
hakkında daha iyi bir resim sunar.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 47/129


Şekil 6. Özel hataların işlenmesi

Kendi uygulamalarınızda, kimlik doğrulama nedeniyle bir hata oluştuğunda, kullanıcı adını ve
parolayı temizleyip ekrana bir hata iletisi eklemeyi düşünebilirsiniz. Eksik komut dosyalarını
ya da diğer 400 tipi hatalarını (izin verilmeyen bir HEAD isteği göndermek gibi kabul
edilemez bir istek yönetimi için 405 ya da yedek sunucu kimlik doğrulamasının gerektiği bir
407 kodu gibi) daha güzel işlemek için benzer yaklaşımlar uygulanabilir. Yaptığınız seçim ne
olursa olsun, sunucudan dönen durum kodunun işlenmesiyle başlar.

Ek istek tipleri

XMLHttpRequest nesnesinin denetimini gerçekten almak istiyorsanız, bu son noktayı göz


önünde bulundurun -- repertuarınıza HEAD isteklerini de ekleyin. Önceki iki makalede, GET
isteklerini nasıl oluşturabileceğinizi göstermiştim; ilerideki bir makalede, POST isteklerini
kullanarak sunucuya veri gönderilmesiyle ilgili tüm ayrıntıları öğreneceksiniz. Gelişmiş hata
işleme ve bilgi toplama amacıyla, HEAD isteklerini nasıl oluşturacağınızı da bilmeniz gerekir.

İstekte bulunma

Aslında bir HEAD isteğinde bulunma oldukça önemsiz bir şeydir; Liste 9'daki gibi basit bir
şekilde, open() yöntemini birinci parametredeki "GET" ya da "POST" yerine "HEAD" ile
çağırırsınız.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 48/129


Liste 9. Ajax ile bir HEAD isteği gönderme
function getSalesData() {
createRequest();
var url = "/boards/servlet/UpdateBoardSales";
request.open("HEAD", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}

Buna benzer bir HEAD isteğinde bulunduğunuzda, sunucu GET ya da POST isteğine
gönderdiği gibi gerçek bir yanıt göndermez. Bunun yerine, yalnızca yanıtın içeriğinin son
değiştirildiği zamanı, istenen kaynağın var olup olmadığını ve diğer ilginç birkaç bilgi biti
içeren üstbilgiler gönderir. Sunucu işleme başlamadan ve kaynağı göndermeden önce, bir
kaynakla ilgili bilgi almak için bunların bir kısmını kullanabilirsiniz.

Bunun gibi bir istekle yapabileceğiniz en kolay şey, yanıt üstbilgilerinin tümünü açıklamaktır.
Bu, HEAD istekleriyle ne alabileceğinizi gösterir. Liste 10'da, bir HEAD isteğinden gelen
yanıt üstbilgilerinin tümünü göstermek için basit bir geri çağrı işlevi sağlanmıştır.

Liste 10. HEAD isteğindeki tüm yanıt üstbilgilerinin yazdırılması


function updatePage() {
if (request.readyState == 4) {
alert(request.getAllResponseHeaders());
}
}

Sunucuya HEAD isteği gönderen basit bir Ajax uygulamasından alınan yanıt üstbilgilerini
gösteren Şekil 7'ye bakın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 49/129


Şekil 7. Bir HEAD isteğinden gelen yanıt üstbilgileri

Bu üstbilgilerin herhangi bir kısmını (sunucu tipinden içerik tipine kadar), Ajax
uygulamasıyla fazladan bilgi ya da işlevsellik sağlamak için ayrı olarak kullanabilirsiniz.

URL'nin denetlenmesi

Bir URL var olmadığında 404 hatasının nasıl denetleneceğini önceden görmüştünüz. Bu genel
bir soruna dönüşürse -- bir komut dosyası ya da sunucu uygulaması sık sık çevrimdışı duruma
geliyor olabilir -- tam bir GET ya da POST isteği göndermeden önce URL'yi denetlemek
isteyebilirsiniz. Bunu yapmak için bir HEAD isteği oluşturun ve geri çağrı işlevinizde 404
hatası olup olmadığını denetleyin; Liste 11'de örnek bir geri çağrı gösterilmiştir.

Liste 11. URL'nin var olup olmadığının denetlenmesi


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
alert("URL exists");
} else if (request.status == 404) {
alert("URL does not exist.");
} else {
alert("Status is: " + request.status);
}
}
}

Dürüst olmak gerekirse, bunun pek bir değeri yoktur. Sunucunun isteğe yanıt vermesi ve
içerik uzunluğunda yanıt üstbilgisini dolduracak bir yanıt bulması gerekir; bu nedenle,

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 50/129


herhangi bir işlem süresi kazanmazsınız. Buna ek olarak, bir istek oluşturmak ve HEAD
isteğini kullanarak URL'nin var olup olmadığını görmek, GET ya da POST isteği oluşturup
daha sonra Liste 7'de gösterilen hataları işlemekle yaklaşık olarak aynı zamanı alır. Yine de
bu bilgilerin elinizde olması bazen yararlı olur; yaratıcılığın ne zaman geleceğini bilemezsiniz
ve HEAD isteğine gereksinim duyarsınız!

Yararlı HEAD istekleri

İçerik uzunluğunu, hatta içerik tipini denetlemek için HEAD isteklerini yararlı bulabilirsiniz.
Bu, bir isteği işlemek için büyük miktarlarda verinin mi gönderileceğini, yoksa HTML, metin
ya da XML yerine sunucunun ikili verileri (ilk üçü JavaScript'te ikili verilerden çok daha
kolay işlenir) göndermeye mi çalışacağını belirleyebilmenizi sağlar.

Bu durumlarda, uygun üstbilgi adını kullanın ve bunu, XMLHttpRequest nesnesindeki


getResponseHeader() yöntemine aktarın. Bir yanıtın uzunluğunu almak için
request.getResponseHeader("Content-Length"); yöntemini çağırın. İçerik tipini almak
için request.getResponseHeader("Content-Type"); yöntemini kullanın.

Birçok uygulamada HEAD isteklerinin eklenmesi herhangi bir işlevsellik katmaz, hatta isteği
yavaşlatabilir (HEAD isteği yanıtla ilgili verileri, ardından gelen GET ya da POST isteği de
gerçek yanıtı almak istediği için). Ancak, bir komut dosyası ya da sunucu tarafındaki bir
bileşenden emin olmamanız durumunda, bir HEAD isteği, yanıt verileriyle uğraşmadan ya da
yanıtı göndermek için bant genişliğini kullanmanıza gerek kalmadan bazı temel verileri
alabilmenizi sağlar.

Sonuç

Birçok Ajax ve Web programcısı için bu makalede anlatılan bilgiler ileri düzey görünebilir.
HEAD isteği oluşturmanın yararı nedir? Hangi durumda JavaScript'inizde açık olarak yeniden
yöneltme durum kodunu işlemeniz gerekir? Bunlar güzel sorular; basit uygulamalarda yanıt,
bu gelişmiş tekniklerin pek değerinin olmadığıdır.

Ancak, Web artık basit uygulamalara tolerans gösterilen bir yer değil; kullanıcılar daha ileri
düzeyli oldular, müşteriler daha güçlü uygulamalar ve gelişmiş hata raporlaması istiyorlar ve
bir uygulama, toplam sürenin %1'inde çalışmadığı için yöneticiler işlerinden çıkarılıyorlar.

O zaman, basit bir uygulamanın ötesine geçip XMLHttpRequest nesnesini daha iyi bir şekilde
anlamak sizin işiniz.

• Çeşitli hazır olma durumlarına güvenebilirseniz -- ve tarayıcılar arasındaki farkları


anlayabilirseniz -- bir uygulamada hızlı bir şekilde hata ayıklayabilirsiniz. Bir hazır
olma durumuna dayalı yaratıcı bir işlevsellik ortaya çıkarabilir ve kullanıcılara ve
müşterilere bir isteğin durumuyla ilgili rapor verebilirsiniz.
• Durum kodlarını kullanabilirseniz, uygulamanızı komut dosyası hatalarıyla,
beklenmedik yanıtlarla ve uç durumlarla başa çıkabilecek şekilde ayarlayabilirsiniz.
Sonuç olarak, uygulamanız yalnızca her şeyin doğru gittiği durumlarda çalışmak
yerine, her zaman çalışır.
• Buna HEAD istekleri oluşturma yeteneğini, URL varlığını denetlemeyi ve bir
dosyanın değiştirilme zamanını öğrenmeyi ekleyin, kullanıcıların kendi bilgileriyle

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 51/129


güncellenmiş, geçerli sayfalar almalarını sağlayın ve (en önemlisi) uygulamanızın ne
kadar güçlü ve çok yönlü olduğunu göstererek kullanıcıları şaşırtın.

Bu makale uygulamalarınızı parıldayan bir uygulama yapmaz, metni sarı spotlarla


vurgulamanıza ya da daha çok masaüstüne benzetmenize de yardımcı olmaz. Bunların tümü
(ve bundan sonraki makalelerde ele alacağımız konular) Ajax'ın güçlü özellikleri olmasına
rağmen, bunlar bir dereceye kadar kekin üzerindeki krema gibidir. Uygulamanızın hataları ve
sorunları uygun bir şekilde işlediği sağlam bir temel oluşturmak için Ajax'ı kullanırsanız,
kullanıcılar sitenize ve uygulamanıza geri döneceklerdir. Buna, sonraki makalelerde sözünü
edeceğim görsel oyunları eklediğinizde, heyecanlı ve mutlu müşterileriniz olacaktır.
(Gerçekten de sonraki makaleyi kaçırmak istemezsiniz!)

Karşıdan yükleme

Açıklama
Bu makaleye ilişkin örnek kod wa-ajaxintro3_ajax-xhr_adv.zip HTTP

Kaynaklar

Bilgi Edinme

• "Introduction to Ajax: Understanding Ajax, a productive approach to building Web


sites, and how it works" (developerWorks, Aralık 2005): Bu dizinin birinci
bölümünde, Ajax bileşen teknolojilerinin birlikte nasıl çalıştığına bakın ve
XMLHttpRequest nesnesini de içeren Ajax'ın merkezi kavramlarını keşfedin.

• "Make asynchronous requests with JavaScript and Ajax: Use XMLHttpRequest for
Web requests" (developerWorks, Ocak 2006): Bu dizinin ikinci bölümünde, tarayıcılar
arasında XMLHttpRequest örneklerinin oluşturulması, isteklerin oluşturulması ve
gönderilmesi ve sunucuya yanıt verilmesini öğrenin.

• "Use Ajax with WebSphere Portal" (developerWorks, Haziran 2006), portal


başarımını geliştirmek, daha temiz bir portal uygulaması mimarisi ve -- en önemlisi --
kullanıcılarınıza çok daha fazla yanıt veren bir portal yaratmak için.

• "Ajax for Java developers: Build dynamic Java applications" (developerWorks, Eylül
2005): Java bakış açısını kullanarak sunucu tarafından Ajax'a bakın vedinamik Web
uygulaması deneyimleri oluşturmak için çığır açan bir yaklaşımla tanışın.

• "Ajax for Java developers: Java object serialization for Ajax" (developerWorks, Ekim
2005): Java nesnesi diziselleştirmesine ilişkin beş yaklaşımı inceleyin veağ üzerinden
nesneleri nasıl göndereceğinizi ve Ajax ile nasıl etkileşime geçeceğinizi öğrenin.

• "Call SOAP Web services with Ajax, Part 1: Build the Web services client"
(developerWorks, Ekim 2005): Ajax'ın var olan SOAP tabanlı Web hizmetleriyle
bütünleştirilmesine ilişkin bu ileri düzey makalede, Ajax tasarım şablonunu kullanarak
Web tarayıcısı tabanlı SOAP Web hizmetleri istemcisini nasıl uygulayacağınızı görün.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 52/129


• Google GMail: Web'in çalışma şeklini değiştiren Ajax tabanlı bu harika uygulamayı
inceleyin. Google Maps, başka bir Google tabanlı Web 2.0 uygulamasıdır.

• Flickr: Web tabanlı bir uygulamada masaüstü hissi vermek için oluşturulan, Ajax'ın
kullanıldığı bu harika örneğe bakın.

• "Ajax: A New Approach to Web Applications": Ajax moniker teriminin ilk kez
kullanıldığı bu makaleyi okuyun -- tüm Ajax geliştiricileri bu makaleyi okumalıdır.

• HTTP durum kodları: Tam listeyi W3C'den alın.

• Head Rush Ajax, Elisabeth Freeman, Eric Freeman ve Brett McLaughlin (Şubat 2006,
O'Reilly Media, Inc.): Bu makaledeki fikirleri beyninize Head First yöntemiyle
yükleyin.

• Java and XML, İkinci Basım, Brett McLaughlin (Ağustos 2001, O'Reilly Media, Inc.):
Yazarın, XHTML ve XML dönüşümleriyle ilgili düşüncelerini okuyun.

• JavaScript: The Definitive Guide, David Flanagan (Kasım 2001, O'Reilly Media,
Inc.): JavaScript ve dinamik Web sayfalarıyla çalışmaya ilişkin kapsamlı yönergeleri
inceleyin. Yayınlanacak olan yeni basımda Ajax ile ilgili iki yeni bölüm vardır.

• Head First HTML with CSS & XHTML, Elizabeth ve Eric Freeman (Aralık 2005,
O'Reilly Media, Inc.): XHTML, CSS ve bu ikisini birlikte kullanmayı öğrenmeyle
ilgili bu eksiksiz kaynağı dikkatle okuyun.

• developerWorks Web mimarisi alanı: Web oluşturma becerilerinizi genişletin.

• developerWorks teknik etkinlikleri ve Web yayınları: Teknik geliştiricilere yönelik bu


yazılım brifinglerini takip edin.

Ürün ve teknoloji edinme

• IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki


geliştirme projenizi oluşturun.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 53/129


Ajax'ta Uzmanlaşma, Bölüm 4:
Web yanıtı için DOM'yi kullanma
Web sayfalarını yanıt verebilir ve etkileşimli kılmak için bir nesne modelini HTML'e
dönüştürme

Düzey: Başlangıç

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

14 Mart 2006

Programcıların (arka uç uygulamalarıyla çalışanlar) ve Web programcıları (zamanlarını


HTML, CSS ve JavaScript yazmakla geçirenler) arasındaki büyük ayrılık çok eskiye dayanır.
Ancak, Belge Nesne Modeli (DOM; Document Object Model), ikisi arasındaki uçurumda bir
köprü görevi görür ve arka uçta XML, ön uçta HTML ile çalışmayı mümkün kılar ve etkili bir
araç olur. Bu makalede, Brett McLaughlin, Belge Nesne Modeli'ni tanıtır, Web sayfalarındaki
kullanımını açıklar ve JavaScript üzerinden kullanımını keşfetmeye başlar.

Birçok Web programcısı gibi, siz de büyük olasılıkla HTML ile çalışmışsınızdır. Programcılar
Web sayfaları üzerinde çalışmaya HTML ile başlar; HTML genellikle, bir uygulamayı ya da
siteyi tamamlamak ve yerleştirme, renk ya da stil üzerindeki son düzenlemeiçin yapılan son
şeydir. HTML kullanımı kadar yaygın bir yanlış anlama da HTML'in ekranda görüntülenmek
üzere tarayıcıya gittikten sonra gerçekte olanlarla ilgilidir. Olanlarla ilgili varsayımlarınızı --
ve bunların neden yanlış olabileceklerini -- derinlemesine incelemeden önce, Web
sayfalarının tasarlanması ve sunulmasıyla ilgili işlemler konusunda her şeyin netleşmesini
istiyorum:

1. Birisi (genellikle siz!) bir metin düzenleyicisinde ya da IDE'de HTML yaratır.


2. HTML'i daha sonra, Apache HTTPD gibi bir Web sunucusuna yüklersiniz ve bunu
Internet ya da intranet üzerinde kullanıcıların erişimine açarsınız.
3. Bir kullanıcı, Firefox ya da Safari gibi bir tarayıcıyla Web sayfanızı ister.
4. Kullanıcının tarayıcısı, Web sunucunuzdan HTML'e ilişkin bir istekte bulunur.
5. Tarayıcı, sunucudan aldığı sayfayı grafik ve metin olarak oluşturur; kullanıcılar Web
sayfasına bakar ve sayfayı etkinleştirirler.

Bu, çok basit görünse de, işler hızla ilginç bir hal alır. Aslında, adım 4 ve 5 arasında
gerçekleşen çok sayıda "ıvır zıvır", bu makalenin odak noktasıdır. Programcıların çoğu, bir
kullanıcının tarayıcısı sayfayı görüntülemek istediğinde biçimlemelerine ne olduğunu aslında
tam olarak hiçbir zaman dikkate almadıkları için buradaki "ıvır zıvır" deyişi gerçekten de bu
durum için geçerlidir:

• Tarayıcı yalnızca HTML içindeki metni okuyor ve görüntülüyor mu?


• Özellikle CSS bir dış dosya içindeyse, CSS için ne söylenebilir?
• Peki ya JavaScript -- o da genellikle bir dış dosyada bulunur?

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 54/129


• Tarayıcı bu öğeleri nasıl işler ve olay işleyicilerini, işlevleri ve stilleri bu metin
biçimlemesiyle nasıl eşler?

Bütün bu sorulara verilecek yanıt Belge Nesne Modeli'dir. O zaman, lafı daha fazlauzatmadan
DOM'ye giriş yapalım.

Web programcıları ve biçimleme

Programcıların çoğu için işleri, Web tarayıcısının başladığı yerde biter. Diğer bir deyişle, bir
HTML dosyasını Web sunucunuzdaki bir dizine gönderdiğinizde, bunu "tamamlanmış" olarak
kabul eder ve (iyi bir olasılıkla) bir daha hiç bu dosyayı düşünmezsiniz! Temiz, iyi
düzenlenmiş sayfalar söz konusu olduğunda da bu harika bir hedeftir; biçimlemenizin, farklı
tarayıcılarda, çeşitli CSS ve JavaScript sürümleriyle olması gerektiği gibi görüntülenmesini
istemenizde yanlış hiçbir şey yoktur.

Buradaki sorun, bu yaklaşımın, bir programcının tarayıcıda gerçekte neler olduğunu


anlamasını sınırlamasıdır. Daha da önemlisi, istemci tarafında JavaScript'ikullanarak Web
sayfasını dinamik bir şekilde güncelleme, değiştirme ve yeniden yapılandırma yeteneği de
sınırlar. Bu sınırlamadan kurtulun ve Web sitelerinizde daha etkileşimli ve daha yaratıcı olun.

Programcının yaptıkları

Sıradan bir Web programcısı olarak, büyük olasılıkla metin düzenleyicinizi ve IDE'nizi
açarsınız ve HTML, CSS ya da JavaScript kodlarını girmeye başlarsınız. Biçim imleri,
seçiciler ve öznitelikleri, yalnızca bir sitenin düzgün görünmesi için gerçekleştirmeniz
gereken basit görevler olarak düşünmek kolaydır. Ancak bu noktanın biraz daha ötesine
geçmek kendinizi zorlamanız gerekir -- bunun yerine, içeriğinizi düzenlediğinizin farkına
varmalısınız. Endişelenmeyin; bu yazının biçimlemenin güzelliğiyle, Web sayfanızın gerçek
potansiyelini nasıl kavramanız gerektiğiyle ya da metafizik diğer konularla ilgili bir derse
dönüşmeyeceğine söz veriyorum. Anlamanız gereken şey, Web geliştirmesi içindeki
rolünüzün tam olarak ne olduğudur.

Bir sayfanın nasıl göründüğü söz konusu olduğunda, en iyi durumda yalnızca önerilerde
bulunabilirsiniz. Bir CSS stil sayfası sunduğunuzda, kullanıcı stil seçimlerinizi geçersiz
kılabilir. Bir yazı tipi büyüklüğü sağladığınızda, bir kullanıcının tarayıcısı bu büyüklükleri
görme engelliler için değiştirebilir ya da bunları, büyük ekranlarda (ve aynı şekilde, büyük
çözünürlüklerde) görüntülemek üzere ölçeklendirebilir. Seçtiğiniz renkler ve yazı tiplerinin
kendileri bile, kullanıcıların ekranlarına ve sistemlerine kurdukları yazı tiplerine tabidir. Bir
sayfanın stili oluştururken elinizden gelenin en iyisini yaparken bile, bir Web sayfası
üzerindeki etkinizi en geniş haliyle kullanmazsınız.

Tam olarak denetleyebildiğiniz şey Web sayfanızın yapısıdır. Biçimlemeniz değiştirilemez ya


da yerine başka biçimleme konulamaz ve kullanıcılar buna karışamaz; tarayıcıları yalnızca
bunu Web sunucusundan alır ve görüntüler (her ne kadar bu işi, sizinkinden çok kullanıcıların
beğenisine göre yapsalar da bu böyledir). Ancak sayfanın düzeni -- bir sözcüğün bu
paragrafın içinde mi yoksa başka bir bölümün içinde mi olduğu -- tamamen size bağlıdır.
Sayfanızın gerçekten değiştirilmesi söz konusu olduğunda (birçok Ajax uygulaması bu
konuya odaklanır), sayfanızın yapısı üzerinde çalışırsınız. Metnin bir parçasının rengini
değiştirmek hoş olabilir, ancak var olan bir sayfaya metin ya da tam bir bölüm eklemek çok

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 55/129


daha önemlidir. Kullanıcının bu bölümü nasıl şekillendirdiğine bakmaksızın, siz sayfanın
düzenlenmesi üzerinde çalışırsınız.

Biçimlemenin yaptıkları

Biçimlemenizin aslında düzenlemeyle ilgili olduğunu fark ettiğinizde, buna farklı bir gözle
bakabilirsiniz. h1 kodunun metnin büyük, siyah ve koyu görünmesine neden olduğu yerine,
bu h1 kodunun başlık olduğunu düşünün. Kullanıcıların metni nasıl gördüğü -- ve sizin
CSS'nizi mi, kendilerininkini mi, yoksa ikisinin bir birleşimini mi kullandıkları -- ikincil
öneme sahiptir. Bunun yerine, biçimlemenin tamamen bu düzenleme düzeyini sağlamayla
ilgili her şeyi kapsadığını anlayın; bir p metnin paragraf olduğunu belirtir, img bir resmi
gösterir, div ise bir sayfayı bölümlere ayırır vb.

Stil ve işleyişin (olay işleyicileri ve JavaScript) bu düzenlemeye bu gerçekten sonra katıldığı


konusunda da net olmalısınız. Üzerinde çalışılabilmesi ya da şekillendirilebilmesi için
biçimlemenin hazır olması gerekir. Dolayısıyla, CSS'yi HTML'niz dışında bir dosyada
tutarken, biçimlemenizin düzeni stilden, formatlamadan ve işleyişten ayrıdır. Bir öğenin ya da
metin parçasının stilini JavaScript uygulamasından değiştirebilirsiniz, ancak biçimlemenizin
düzenini değiştirmek daha ilginçtir.

Biçimlemenizin yalnızca sayfanıza ilişkin bir düzen ya da çerçeve sağladığını göz önünde
bulundurduğunuz süre, oyunda bir adım öndesiniz demektir. Birazdan, tarayıcının tüm bu
metin düzenini nasıl aldığını ve nasıl daha ilginç bir şeye -- değiştirilebilen, arasına ekleme
yapılabilen ya da silinebilen bir nesneler takımına -- dönüştürdüğünü göreceksiniz.

Biçimleme üzerine bazı


düşünceler

Düz metin düzenlemesi: Doğru


mu, yanlış mı?
Biçimleme kodlarını saklamak
için düz metin dosyaları ideal
yerlerdir, ancak biçimlemeleri
düzenlemek için bu geçerli
değildir. Web sayfası
biçimlemeleri üzerinde çalışmak
için Macromedia DreamWeaver -
- biraz daha zorlayıcı olunursa
Microsoft® FrontPage® -- gibi
bir IDE mükemmel bir seçimdir.
Bu ortamlar genellikle, özellikle
de her biri gerçek bir sayfanın
biçimlemesinin dışındaki bir
dosyadan alınan CSS ve
JavaScript kodları
kullandığınızda, Web sayfalarının
yaratılması için kısayollar ve
yardım sağlar. Programcıların
çoğu hala eski Notepad ya da

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 56/129


vi'yi tercih etmektedirler (itiraf
ediyorum ben de onlardan
biriyim) ve bunlar da iyi birer
seçenektir. Her iki durumda da
sonuç, biçimlemeyle dolu bir
metin dosyasıdır.

Ağ üzerinde metin: İyi bir şey


Daha önce de belirtildiği gibi,
metin, ağ üzerinden yüzlerce ve
binlerce kez aktarılan bir belge
(HTML ya da CSS gibi) için
harika bir ortamdır. Tarayıcının
metni göstermekte zorlandığını
söylediğimde, bunu özellikle
metni kullanıcıların
görüntüledikleri görsel ve grafik
sayfaya dönüştürme anlamında
kullandım. Aslında bunun,
tarayıcının dosyayı Web
sunucusundan alma şekliyle bir
ilgisi yoktur; bu durumda, metin
hala en iyi seçenek olmaya
devam eder.

Metin biçimlemesinin avantajları

Web tarayıcısına geçmeden önce, düz metnin HTML'nizi saklamak için neden kesinlikle en
iyi seçim olduğu üzerinde düşünebiliriz (bu konuda daha fazla bilgi edinmek için bkz.
Biçimleme üzerine bazı ek düşünceler). İyi ve kötü yönlerini ele almadan, HTML'nizin
sayfanın her görüntülenişinde ağ üzerinden bir Web tarayıcısına gönderildiğini hatırlayın
(basitleştirmek adına önbelleğe alma vb. görevleri bir kenara koyun). Kısacası, metnin
aktarılmasından daha etkili başka bir yaklaşım yoktur. İkili nesneler, sayfanın grafik
gösterimleri, büyük miktarlarda yeniden düzenlenen biçimlemeler ... bunların hiçbiri, ağ
üzerinden düz metin dosyaları kadar kolay gönderilemez.

Buna bir de tarayıcının bu formüle kattığı değeri ekleyin. Günümüzde kullanılan tarayıcılar,
kullanıcıların metnin büyüklüğünü değiştirebilmelerini, resimleri ölçeklendirebilmelerini, bir
sayfaya ilişkin CSS ya da JavaScript dosyasını yükleyebilmelerini (çoğu durumda) ve daha
birçok şeyi sağlamaktadır -- bunların tümü, sayfanın herhangi bir grafik gösteriminin
tarayıcıya gönderilmesini engeller. Bunun yerine, tarayıcı, sayfayı tarayıcıda işlemek için
gerekli işlemleri uygulamak üzere ham HTML'ye gereksinim duyar; böylece sayfanın
işlenmesi için sunucuya güvenmesi gerekmez. Aynı şekilde, CSS'yi JavaScript'ten ve bunları
HTML biçimlemesinden ayırmak için ayrılması kolay bir formatın kullanılması gerekir. Bunu
gerçekleştirmek için metin dosyaları kullanmak yine harika bir seçenektir.

Son, ancak bir o kadar da önemli bir şey de HTML 4.01 ve XHTML 1.0 ve 1.1 gibi yeni
standartların, içeriği (sayfanızdaki veriler) gösterimden ve stilden (genellikle CSS tarafından
uygulanır) ayırma konusundaki vaadlerini hatırlamanızdır. Programcıların HTML'lerini

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 57/129


CSS'lerinden ayırmak, daha sonra da tüm bunların yeniden birleştirildiği bir sayfanın
gösterimi almak için tarayıcıyı zorlamak bu standartların avantajlarının çoğunu ortadan
kaldırır. Tarayıcıya kadar bu tamamen farklı parçaları ayrı tutmak, tarayıcıya HTML'yi
sunucudan alırken büyük esneklik sağlar.

Web tarayıcılarına daha yakın bir bakış

Bazılarınız için şimdiye kadar okuduklarınız, Web geliştirme sürecindeki rolünüzün genel bir
gözden geçirmesi gibi olabilir. Ancak Web tarayıcısının yaptıkları söz konusu olduğunda, en
usta Web tasarımcılarının ve geliştiricilerinin birçoğu "kapağın altında" gerçekte olup bitenin
farkına bile varmaz. Bu bölümde bu konuya odaklanacağım. Endişelenmeyin, birazdan kodlar
da gelecek, ancak kodlarla ilgili sabırsızlığınız konusunda kendinizi biraz daha tutun, çünkü
bir Web tarayıcısının yaptıklarını gerçekten tam olarak anlamak, kodlarınızın doğru
çalışmasıaçısından büyük önem taşır.

Metin biçimlemesinin dezavantajları

Metin biçimlemesinin bir tasarımcı ya da sayfa yaratıcısı için inanılmaz avantajları olduğu
gibi, tarayıcı açısından önemli dezavantajları da vardır. Özellikle, tarayıcılar metin
biçimlemesini bir kullanıcıya doğrudan gösterirken zorlanmaktadır (bu konuda daha fazla
bilgi edinmek için Biçimleme üzerine bazı ek düşünceler konusuna bakın). Bu yaygın tarayıcı
görevlerini gözden geçirin:

• CSS stillerini (bunlar genellikle dış dosyalardaki birden çok stil sayfalarından
alnır),öğenin tipi, sınıfı, tanıtıcısı ve HTML içindeki konumuna bağlı olarak
biçimlemeye uygulama.
• Stilleri ve formatlamayı, JavaScript koduna göre (bu da genellikle dış dosyalarda
bulunur)HTML bölgesinin farklı parçalarına uygulama.
• JavaScript koduna göre form alanlarının değerini değiştirme.
• JavaScript koduna göre resim kaydırma ve resim değiştirme gibi görsel etkileri
destekleme.

Karmaşıklık, bu görevlerin kodlanmasında değildir; bunların her birini yapmak oldukça


kolaydır. Karmaşıklık, istenen işlemi gerçekte yerine getiren tarayıcıdan kaynaklanmaktadır.
Biçimleme, metin olarak saklanıyorsa ve örneğin, center-text sınıfındaki bir p öğesinde
bulunan metni ortalamak isterseniz (text-align: center), bunu nasıl gerçekleştirirsiniz?

• Metne yerleşik stil mi eklersiniz?


• Stili tarayıcıdaki HTML metnine uygular ve hangi içeriğin ortalanacağını ya da
ortalanmayacağını mı izlersiniz?
• Biçimlendirilmemiş HTML uygular ve işlemden sonra biçimi mi uygularsınız?

Oldukça zor olan bu sorular, bugünlerde tarayıcıları çok az sayıda kişinin


kodlamasınınnedenidir. (Bunu yapanlara gönülden bir "Teşekkürler!" demek gerekir)

Açıkça görülüyor ki, ilk aşamada bir sayfanın biçimlemesini alırken metin iyi bir çözüm
olmasına rağmen, tarayıcıya ilişkin HTML'in saklanması için düz metin pek iyi bir yöntem
değildir. Buna, JavaScript kodlamasının sayfanın yapısını değiştirebileceğini de eklerseniz
işler karışabilir. Tarayıcı, değiştirilen yapıyı diske yeniden mi yazmalı? Tarayıcı, belgenin şu
anki aşamasının ne olduğunu nasıl belirleyecek?

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 58/129


Açıkçası, yanıt metin değil. Metnin değiştirilmesi zordur, stil ve işleyiş ekleme bakımından
esnek değildir ve son olarak günümüzün Web sayfalarının dinamik doğasıyla çok az benzerlik
taşır.

Ağaç görünümüne geçiş

Bu sorunun yanıtı -- en azından, günümüzde Web tarayıcılarının seçtiği yanıt -- HTML'yi


göstermek için bir ağaç yapısının kullanılmasıdır. Metin biçimlemesi olarak gösterilen,
oldukça basit ve biraz da sıkıcı HTML sayfası örneği olan Liste 1'e bakın.

Liste 1. Metin biçimlemesiyle oluşturulmuş basit HTML sayfası


<html>
<head>
<title>Trees, trees, everywhere</title>
</head>
<body>

<h1>Trees, trees, everywhere</h1>


<p>Welcome to a <em>really</em> boring page.</p>
<div>

Come again soon.


<img src="come-again.gif" />
</div>
</body>
</html>

Tarayıcı bunu alır ve Şekil 1'deki gibi ağaca benzer bir yapıya dönüştürür.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 59/129


Şekil 1. Liste 1'in ağaç görünümü

Bu makaleyi izleyebilmeniz için birkaç tane çok küçük basitleştirme yaptım. DOM ya da
XML konusunda uzman olanlar, boş alanın, bir belgedeki metnin Web tarayıcısının ağ
yapısında nasıl gösterileceği ve kesileceği üzerinde bir etkiye sahip olabileceğini fark
edeceklerdir. Bu konuya girersek kafalar iyice karışacaktır, bu nedenle beyaz alanın etkisiyle
ilgili bilginiz varsa, harika; ama yoksa, okumaya devam edin ve bu konudaendişelenmeyin.
Bu bir soruna dönüştüğünde, ihtiyacınız olan her şeyi o zaman bulabilirsiniz.

Gerçek ağaç arka planı dışında burada fark edebileceğiniz ilk şey, ağaçtaki her şeyin, en
dıştaki, HTML'in kapsayıcı öğesi olan html öğesinden başladığıdır. Buna, ağaç benzetmesi
korunarak kök öğe denir. Ağacın en altında olmasına rağmen, ağaçlara bakarken ve ağaçları
çözümlerken her zaman buradan başlayın. Size yardımcı olacaksa, her ne kadar ağaç
benzetmesini bozsa da, her şeyi tersine çevirebilirsiniz.

Kökten, biçimlemenin farklı parçaları arasındaki ilişkileri gösteren çizgiler çıkar. head ve
body öğeleri, html kök öğesinin alt öğeleridir; title, head öğesinin ve "Trees, trees,
everywhere" metni de title öğesinin alt öğesidir. Tarayıcı, Şekil 1'de gördüğünüze benzer
bir yapı alıncaya kadar tüm ağaç bu şekilde düzenlenir.

Ek birkaç terim

Ağaç benzetmesine devam edersek, head ve body öğelerinin html öğesinin dalları olduğu
söylenir. Kendi içlerinde alt öğeleri de olduğu için bunlar dallardır. Ağacın uç noktalarına

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 60/129


vardığınızda, genellikle "Trees, trees, everywhere" ve "really" gibi metinlerle karşılaşırsınız.
Kendi içlerinde alt öğelere sahip olmadıkları için bunlara da genellikle yapraklar denir. Tüm
bu terimleri ezberlemenize gerek yoktur ve belirli bir terimin anlamını çıkarmak için ağaç
yapısını gözünüzün önüne getirmek çoğu zaman daha kolay olacaktır.

Nesnelerin değeri

Temel terminolojinin bir kısmını öğrendiğinize göre, içinde öğe adlarının ve metinlerin
bulunduğu küçük dikdörtgenlerin üzerinde odaklanmanın zamanı geldi (Şekil 1).
Dikdörtgenlerin her biri bir nesnedir; tarayıcı, metinle ilgili bu sorunların bir kısmını burada
çözer. HTML belgesinin her bir parçasını gösteren nesneler kullanıldığında, düzenlemeyi
değiştirmek, stilleri uygulamak, JavaScript'in belgeye erişimine izin vermek ve daha birçok
işlem oldukça kolaylaşır.

Nesne tipleri ve özellikleri

Olası biçimleme tiplerinin her birinin kendi nesne tipi vardır. Örneğin, HTML'nizdeki öğeler
bir Element nesne tipiyle gösterilir. Belgenizdeki metin bir Text tipiyle, öznitelikler
Attribute tipleriyle gösterilir ve diğer öğeler için de bu böyle devam eder.

Yani Web tarayıcısı yalnızca belgenizi göstermek için bir nesne modeli kullanmakla kalmaz
(statik metinle uğraşmaktan kaçar), aynı zamanda nesne tipine göre bir şeyin ne olduğunu
hemen tanımlayabilir. HTML belgesi ayrıştırılır ve Şekil 1'de gördüğünüze benzer nesne
takımlarına dönüştürülür; böylece, köşeli parantez ve ters bölme işaretleri gibi şeyler (örneğin
< için < ve > için >) artık sorun olmaktan çıkar. Bu, tarayıcının işini, en azından giriş
HTML'sini ayrıştırdıktan sonra, çok daha kolaylaştırır. Bir şeyin öğe mi, yoksa bir öznitelik
mi olduğunu anlamak ve bu nesne tipiyle yapılacak işlemi belirlemek basittir.

DAha sonra Web tarayıcısı, nesneleri kullanarak bu nesnelerin özelliklerini değiştirebilir.


Örneğin, her bir öğe nesnesinin bir üst öğesi ve bir alt öğe listesi vardır. Yeni bir alt öğe ya da
metin eklediğinizde, yalnızca bir öğenin alt öğe listesine yeni bir alt öğe eklemiş olursunuz.
Bu nesnelerin ayrıca style özellikleri vardır, bu nedenle bir öğenin ya da metin parçasının
biçimini anında değiştirmek önemsiz bir şey olur. Örneğin, JavaScript kullanarak bir div
öğesinin yüksekliğini aşağıdaki şekilde değiştirmek isteyebilirsiniz:

someDiv.style.height = "300px";

Diğer bir deyişle, Web tarayıcısı bunun gibi nesne özelliklerini kullanarak ağacın
görünümünü ve yapısını çok kolay bir şekilde değiştirebilir. Bunu, tarayıcının sayfayı iç metin
olarak göstermesi durumunda yapması gereken karmaşık işlemlerle karşılaştırın;
özelliklerdeki ya da yapıdaki her değişiklik tarayıcının statik dosyayı yeniden yazmasını,
yeniden ayrıştırmasını ve ekranda yeniden görüntülemesini gerektirir. Bunların tümü
nesnelerle mümkün hale gelir.

Bu noktada, HTML belgelerinizin bazılarını açın ve bunları ağaçlar olarak çizin. Pek alışıldık
bir istek gibi görünmese de -- özellikle çok az kodun bulunduğu bir makalede -- bu ağaçları
beceriyle kullanmak istiyorsanız, bu ağaçların yapılarını öğrenmeniz gerekir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 61/129


Bunu gerçekleştirirken, bazı garipliklerle karşılaşabilirsiniz. Örneğin, aşağıdaki durumları
düşünün:

• Özniteliklere ne oluyor?
• em ve b gibi öğelerle ayrılan metne ne oluyor?
• Ve doğru bir şekilde yapılandırılmayan HTML ne oluyor? (Örneğin kapanış p biçim
imi eksik olduğunda)

Bu tür sorunları gördükten sonra, aşağıdaki birkaç bölümü çok daha iyi anlayacaksınız.

Sıkı kurallar bazen iyidir

Az önce bahsettiğim alıştırmayı denediyseniz, biçimlemenizin ağaç görünümüyle ilgili olası


sorunların bazılarını bulmuş olabilirsiniz (dediğimi yapmadıysanız, sözüme inanın!). Aslında,
bunların birkaçını Liste 1 ve Şekil 1'de, p öğesinin bölünme şeklinden çıkarmış olabilirsiniz.
Sıradan bir Web geliştiricisine p öğesinin metin içeriğini sorarsanız, en genel yanıt "Welcome
to a really boring Web page." olacaktır. Bunu Şekil 1 ile karşılaştırırsanız, bu yanıtın --
mantıklı olmasına rağmen -- çok da doğru olmadığını görürsünüz.

p öğesinin üç farklı alt nesnesi vardır ve bunların hiçbiri, "Welcome to a really boring Web
page." metninin tamamını içermemektedir. Bu metnin, "Welcome to a" ve " boring Web
page" gibi parçalarını bulabilirsiniz, ancak tamamını bulamazsınız. Bunu anlamak için
biçimlemenizdeki her şeyin, bir nesne tipine dönüştürülmesi gerektiğini hatırlayın.

Dahası, bunların sırası da önemlidir! Kullanıcıların, doğru biçimlemeyi gösteren, ancak bunu
HTML'nizde sağladığınızdan farklı bir sırada gerçekleştiren bir tarayıcıya nasıl yanıt
vereceklerini düşünebiliyor musunuz? Paragraflar, başlıklar ve üst başlıklar arasında
sıkışmıştır, kendiniz belgeyi böyle düzenlemediğinizde bile bu böyledir. Açıkça görülüyor ki
tarayıcının, öğelerin ve metnin sırasını koruması gerekir.

Bu durumda, p öğesinin üç ayrı parçası vardır:

• em öğesinden önce gelen metin


• em öğesinin kendisi
• em öğesinden sonra gelen metin

Bu sıralamayı karıştırırsanız, vurguyu metnin yanlış bir kısmına yükleyebilirsiniz. Bunu


doğru bir şekilde gerçekleştirmek için, p öğesinin, Liste 1'deki HTML'de göründüğü sırada
yer alan üç nesne alt öğesi vardır. Dahası, vurgulanan "really" metni p öğesinin bir alt öğesi
değildir; p öğesinin alt öğesi olan em öğesinin bir alt öğesidir.

Bu kavramı anlamanız sizin için çok büyük önem taşır. "really" metni p öğesinin metninin
geri kalanıyla birlikte görüntülenecek olsa bile, bu yine de em öğesinin bir doğrudan alt
öğesidir. p öğesinin geri kalanından farklı bir formatlamaya sahip olabilir ve metnin geri
kalanından bağımsız olarak hareket ettirilebilir.

Bunu aklınıza iyice kazımak için Liste 2 ve 3'teki HTML'in şemalarını çıkarmayı deneyin ve
metni, doğru üst öğeyle birlikte ele aldığınızda emin olun (metin ekranda nasıl görüntülenirse
görüntülensin).

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 62/129


Liste 2. Öğelerin biraz ustalıklı bir şekilde iç içe yerleştirilmesini içeren bir biçimleme
<html>
<head>
<title>This is a little tricky</title>
</head>
<body>

<h1>Pay <u>close</u> attention, OK?</h1>


<div>
<p>This p really isn't <em>necessary</em>, but it makes the
<span id="bold-text">structure <i>and</i> the organization</span>

of the page easier to keep up with.</p>


</div>
</body>
</html>

Liste 3. Öğelerin daha da ustalıklı bir şekilde iç içe yerleştirilmesi


<html>
<head>
<title>Trickier nesting, still</title>
</head>
<body>

<div id="main-body">
<div id="contents">
<table>
<tr><th>Steps</th><th>Process</th></tr>

<tr><td>1</td><td>Figure out the <em>root element</em>.</td></tr>


<tr><td>2</td><td>Deal with the <span id="code">head</span> first,
as it's usually easy.</td></tr>

<tr><td>3</td><td>Work through the <span id="code">body</span>.


Just <em>take your time</em>.</td></tr>

</table>
</div>
<div id="closing">
This link is <em>not</em> active, but if it were, the answers
to this <a href="answers.html"><img src="exercise.gif" /></a> would
be there. But <em>do the exercise anyway!</em>

</div>
</div>
</body>
</html>

Bu alıştırmaların yanıtlarını, bu makalenin sonundaki GIF dosyalarında (Şekil 2'de tricky-


solution.gif ve Şekil 3'te trickier-solution.gif) bulabilirsiniz. Bunları kendi başınıza çözmeye
çalışmadan yanıtlarına bakmayın. Bunlar, ağacı düzenlemede sıkı kuralların nasıl

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 63/129


uygulandığını anlamanıza ve HTML ve ağaç yapısı konusunda uzmanlaşmanıza yardımcı
olacaktır.

Özniteliklere ne oluyor?

Özniteliklerle ne yapacağınızı anlamaya çalışırken herhangi bir sorunla karşılaştınız mı?


Önceden belirttiğim gibi, özniteliklerin de kendi nesne tipleri vardır, ancak bir öznitelik
gerçekte bağlı göründüğü öğenin alt öğesi değildir -- iç içe geçen öğeler ve metin, bir
özniteliğin aynı "düzeyinde" bulunmazlar ve Liste 2 ve 3'teki alıştırmaların yanıtlarında,
gösterilen öznitelik bulunmadığını fark edeceksiniz.

Öznitelikler aslında, tarayıcının kullandığı nesne modelinde saklanır, ancak bunlarınki biraz
özel bir durumdur. Her bir öğenin, alt nesne listesinden ayrı, kullanılabilir bir öznitelik listesi
vardır. Dolayısıyla bir div öğesinin, "id" özniteliğini ve "class" özniteliğini içeren bir listesi
olabilir.

Bir öğeye ilişkin özniteliklerin, benzersiz adları olması gerektiğini unutmayın; diğer bir
deyişle, bir öğenin iki tane "id" ya da iki tane "class" özniteliği olamaz. Bu, listeyi takip
etmeyi ve listeye erişimi çok kolaylaştırır. Sonraki makalede de göreceğiniz gibi, bir
özniteliğin değerini adına göre almak için yalnızca getAttribute("id") gibi bir yöntemi
çağırabilirsiniz. Benzer yöntem çağrılarıyla öznitelik ekleyebilir ve var olan özniteliklerin
değerini ayarlayabilirsiniz (ya da sıfırlayabilirsiniz).

Öznitelik adlarının benzersiz olmasının, bu listeyi, alt nesne listesinden farklı kıldığını da
hatırlatalım. Bir p öğesinin içinde birden çok em öğesi olabilir; bu nedenle, alt nesne listesi
yinelenen öğeler içerebilir. Alt nesne listesi ve öznitelik listesi benzer şekilde çalışır, ancak
biri yinelenen öğeler içerirken (bir nesnenin alt öğeleri), diğeri içermez (bir öğe nesnesinin
öznitelikleri). Son olarak, yalnızca öğelerin öznitelikleri olabildiğinden, metin nesnelerinin
öznitelikleri saklayacak bağlı listeleri olmaz.

Özensiz HTML

Devam etmeden önce, tarayıcının biçimlemeyi bir ağaç gösterimine dönüştürmesiyle ilgili bir
konu üzerinde daha durmalıyız -- tarayıcı iyi hazırlanmamış biçimlemeyi nasıl işler. İyi
hazırlanmış, aslında XML'de yaygın bir şekilde kullanılan bir terimdir ve iki temel anlamı
vardır:

• Her açılış biçim iminin, bununla eşleşen bir de kapanış biçim imi vardır. Belgedeki her
<p> biçim imi bir </p>, her <div> biçim imi bir </div> biçimimi ile eşleşir.
• En içteki açılış biçim imi, en içteki kapanış biçim imiyle eşleşir; daha sonra bir sonraki
en içteki açılış biçim imi, bir sonraki kapanış biçimimiyle eşleşir, vb. Dolayısıyla,
<b><i>bold and italics</b></i> biçim imi, en içteki açılış biçim imi -- <i> -- en
içteki kapanış biçim imiyle -- <b> -- yanlış eşleştiği için geçersiz olur. Bunu iyi bir
şekilde hazırlamak için, açılış biçim iminin sırasını ya da kapanış biçim iminin sırasını
değiştirmeniz gerekir. (Her ikisini de değiştirirseniz, sorun yine devam eder.)

Bu iki kuralı iyi çalışın. Bu iki kural yalnızca belgenin basit bir şekilde düzenlenmesini
sağlamak kalmaz, aynı zamanda belirsizliğin de ortadan kalkmasını sağlar. Önce koyu, sonra
italik biçim mi uygulanmalı? Yoksa tersi mi yapılmalı? Bu sıralama ve belirsizlik büyük bir
sorun gibi görünmüyorsa, CSS'nin kuralların başka kuralları iptal etmesine izin verdiğini

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 64/129


hatırlayın; dolayısıyla, örneğin b öğelerinin içindeki metne ilişkin yazı tipi i öğelerinin
içindeki metne ilişkin yazı tipinden farklıysa, formatlamanın uygulandığı sıra çok önem
kazanır. Bu nedenle, bir HTML sayfasının iyi bir şekilde hazırlanmasının önemi burada
devreye girer.

Tarayıcının iyi hazırlanmamış bir belge aldığı durumlarda, tarayıcı elinden gelenin en iyisini
yapar. Sonuçta ortaya çıkan ağaç yapısı, en iyi ihtimalle özgün sayfa yazarının tasarladığına
yakın bir şey ve en kötü ihtimalle, tamamen farklı bir şey olacaktır. Sayfanızı bir tarayıcıya
yüklediyseniz ve tamamen beklenmedik bir şeyle karşılaştıysanız, bir tarayıcının yapınızın ne
olması gerektiğini tahmin etmeye çalıştığında ve işini başarısız bir şekilde yaptığında ortaya
çıkan sonucu görmüş olabilirsiniz. Elbette, bu sorunun çözümü oldukça basittir:
Belgelerinizin iyi hazırlandığından emin olun! Buna benzer standartlaştırılmış HTML'in nasıl
yazılacağı konusunda şüpheleriniz varsa, yardım için Kaynaklar bölümüne bakın.

DOM'ye giriş

Şimdiye kadar tarayıcıların bir Web sayfasını bir nesne gösterimine dönüştürdüğünü
öğrendiniz ve belki de nesne gösteriminin bir DOM ağacı olduğunu tahmin ettiniz. DOM,
Document Object Model (Belge Nesne Modeli) teriminin kısaltmasıdır ve W3C'de (World
Wide Web Consortium) bulabileceğiniz bir belirtimdir (Kaynaklar bölümünde DOM ile ilgili
birkaç bağlantı bulabilirsiniz).

Ancak daha da önemlisi DOM, nesnelerin, tarayıcının biçimlemeyi göstermesini sağlayan


tiplerini ve özelliklerini tanımlar. (Bu dizinin bir sonraki makalesi, JavaScript ve Ajax
kodunuzdan DOM'nin kullanılması üzerine odaklanmaktadır.)

Belge nesnesi

Birinci ve en önemli nokta, nesne modelinin kendisine erişmeniz gerektiğidir. Bu oldukça


kolaydır; Web sayfanızda çalışan JavaScript kodunun herhangi bir parçasında yerleşik
document değişkenini kullanmak için kodu aşağıdaki gibi yazabilirsiniz:

var domTree = document;

Elbette, bu kodun tek başına hiçbir yararı yoktur, ancak her Web tarayıcısının, document
nesnesini JavaScript kodu tarafından kullanılabilir kıldığını ve nesnenin, tam biçimleme
ağacını temsil ettiğini gösterir (Şekil 1).

Her şey bir düğümdür

Açıkça görülüyor ki document nesnesi önemlidir, ancak aynı zamanda yalnızca bir
başlangıçtır. Daha ileriye gitmeden önce, bir terim daha öğrenmeniz gerekir: düğüm.
Biçimlemenin her bir parçasının bir nesneyle temsil edildiğini zaten biliyorsunuz, ancak bu
herhangi bir nesne değildir -- bu, belirli bir nesne tipi, DOM düğümüdür. Daha özel tipler --
metin, öğeler ve öznitelikler gibi -- bu temel düğüm tipinden genişler. Böylece elinizde, metin
düğümleri, öğe düğümleri ve öznitelik düğümleri vardır.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 65/129


JavaScript'te çok programlama yaptıysanız, DOM kodunu önceden kullandığınız hissine
kapılabilirsiniz. Şimdiye kadar yayınlanan Ajax dizilerini takip ettiyseniz, kesinlikle bir
süredir DOM kodunu kullanıyor olmalısınız. Örneğin, var number =
document.getElementById("phone").value; satırında, belirli bir öğeyi (bu örnekte, bir
form alanıdır) bulmak ve daha sonra, bu öğenin değerini almak için DOM kullanılır. Henüz
fark etmediyseniz de, JavaScript kodunuza document nesnesini her yazışınızda DOM'yi
kullandınız.

O zaman öğrendiğiniz terimleri sadeleştirmek amacıyla, DOM ağacının, bir nesne ağacı
olduğu, ancak daha özel bir şekilde bir düğüm nesneleri ağacı olduğunu söyleyebiliriz. Ajax
uygulamalarında -- ya da diğer herhangi bir JavaScript'te -- bir öğenin ve içeriğinin
kaldırılması, metnin belirli bir parçasının vurgulanması ya da yeni bir resim öğesinin
eklenmesi gibi etkileri yaratmak için bu düğümleri kullanabilirsiniz. Bunların tümü istemci
tarafında (Web tarayıcınızda çalışan kod) gerçekleştiği için, bu etkiler sunucuyla iletişim
kurulmadan hemen etkin olur. Web sayfasındaki öğeler, sunucuya istek gönderilip gelen yanıt
yorumlanırken karşılaşılan çok uzun duraklamalar olmadan değiştiği için sonuçta ortaya çıkan
uygulama genellikle daha yanıt verici olduğu hissini verir.

Programlama dillerinin çoğunda, her bir düğüm tipine ilişkin gerçek nesne adlarını
öğrenmeniz, kullanılabilir özellikleri öğrenmeniz ve tipleri ve seçimleri anlamanız gerekir;
ancak JavaScript'te bunların hiçbiri gerekli değildir. Basit bir şekilde bir değişken yaratabilir
ve bunu, istediğiniz nesneye atayabilirsiniz (önceden de gördüğünüz gibi):

var domTree = document;


var phoneNumberElement = document.getElementById("phone");
var phoneNumber = phoneNumberElement.value;

Herhangi bir tip yoktur ve JavaScript değişkenlerin yaratılmasını ve gerekli şekilde doğru
tiplere atanmalarını sağlar. Sonuç olarak, JavaScript üzerinden DOM kullanımı oldukça basit
bir şey olur (sonraki bir makalede DOM'nin XML ile ilişkisi ele alınacaktır ve işler, o noktada
biraz daha hassaslaşır).

Sonuç

Bu noktada, sizi biraz heyecanlı bir dizinin ortasında bırakır gibi olacağım. Açıkçası, bu
makale DOM'yi tam olarak tüm ayrıntılarıyla kapsayan bir yazı olmadı; aslında, bu makale
DOM'ye girişten biraz daha fazlasını içeriyor. DOM konusunda anlatılacak, bugün size
anlattığımdan çok daha fazla şey var!

Bu dizinin bir sonraki makalesi, bu düşünceleri biraz daha genişletecek ve DOM'yi, Web
sayfalarını güncellemek, HTML'inizde hızla değişiklikler yapmak ve kullanıcınıza daha
etkileşimli bir deneyim yaratmak için JavaScript ile nasıl kullanabileceğiniz üzerinde
duracaktır. Ajax isteklerinizde XML kullanılmasına ilişkin sonraki makalelerimde DOM
konusuna yeniden döneceğim. Bu yüzden DOM'yi öğrenin; DOM, Ajax uygulamalarınızın
ana parçalarından biri olacak.

Bu noktada DOM ile ilgili daha ayrıntılı bilgiler vermek daha kolay olurdu; DOM ağacında
hareket etmeyle ilgili ayrıntılar, öğe ve metin değerlerini alma, düğüm listelerinde dolaşma ve

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 66/129


daha birçok konu. Ancak bunlar, sizde DOM'nin kodla ilgili olduğu izlenimini yaratırdı -- ki
öyle değil.

Bir sonraki makaleye geçmeden önce, ağaç yapıları üzerine biraz düşünmeyi deneyin ve kendi
HTML'niz üzerinde çalışıp bir Web tarayıcısının HTML'yi biçimlemenin bir ağaç
görünümüne nasıl dönüştürdüğünü inceleyin. Ayrıca, bir DOM ağacı düzenlemesiyle ilgili
düşünün ve bu makalede anlatılan özel durumlarla ilgili çalışın: öznitelikler, içinde öğelerin
karıştırıldığı metin, metin içeriği olmayan öğeler (img öğesi gibi).

Bu kavramları iyice kavrarsanız ve daha sonra, JavaScript ve DOM sözdizimini öğrenirseniz


(sonraki makalede), yanıt verme yeteneğini çok daha kolay geliştirebilirsiniz.

Ve sakın unutmayın: burada Liste 2 ve 3'ün yanıtları bulunmaktadır -- bunlar aynı zamanda
örnek kodun da içindedir!

Şekil 2. Liste 2'nin yanıtı

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 67/129


Şekil 3. Liste 3'ün yanıtı

Kaynaklar

Bilgi Edinme

• Ajax'a giriş konusunda yayınlanan developerWorks serisinin önceki makalelerine


bakın:
o "Introduction to Ajax: Understanding Ajax, a productive approach to building
Web sites, and how it works:" (Ajax'a Giriş: Web siteleri oluşturmak için
kullanılan verimli bir yaklaşım olarak Ajax'ı ve nasıl çalıştığını anlama )
başlıklı Bölüm 1'de, Ajax bileşen teknolojilerinin birlikte nasıl çalıştığı
gösterilmekte ve XMLHttpRequest nesnesinin de içinde bulunduğu Ajax'ın
merkezi kavramları ortaya çıkarılmaktadır (Aralık 2005).
o "Make asynchronous requests with JavaScript and Ajax: Use
XMLHttpRequest for Web requests:" (JavaScript ve Ajax ile zamanuyumsuz
istekler oluşturma: Web istekleri için XMLHttpRequest kullanma) başlıklı
Bölüm 2'de, tarayıcılar arasında XMLHttpRequest örneklerinin nasıl
yaratılacağı, isteklerin oluşturulması ve gönderilmesi ve sunucuya yanıt
verilmesi gösterilmektedir (Ocak 2006).
o "Advanced requests and responses in Ajax:" (Ajax'ta gelişmiş istekler ve
yanıtlar) başlıklı Bölüm 3'te, standart Web formlarının Ajax ile çalışması ve
HTTP durum kodlarıyla, hazır olma durumlarıyla ve XMLHttpRequest
nesnesiyle ilgili bilgilerinizi nasıl artırabileceğiniz gösterilmektedir (Şubat
2006).
• "Use Ajax with WebSphere Portal" (developerWorks, Haziran 2006), portal
başarımını geliştirmek, daha temiz bir portal uygulaması mimarisi ve -- en önemlisi --
kullanıcılarınıza çok daha fazla yanıt veren bir portal yaratmak için.

• World Wide Web Consortium'daki DOM Ana Sayfası: DOM ile ilgili her şeyin
başlangıç noktası olan bu siteyi ziyaret edin.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 68/129


• DOM Level 3 Core Specification (DOM Düzey 3 Çekirdek Belirtimi): Çeşitli
dillerden Belge Nesne Modeli'nin kullanabileceği tipleri ve özellikleri kullanarak
çekirdek DOM'yi tanımlayın.

• ECMAScript language bindings for DOM (DOM için ECMAScript dil


ilişkilendirmeleri): Bir JavaScript programcısıysanız ve kodunuz için DOM kullanmak
istiyorsanız, Düzey 3 Belge Nesne Modeli Çekirdeği tanımlarına ilişkin bu ek ilginizi
çekecektir.

• "Ajax for Java developers: Build dynamic Java applications:" Java bakış açısını
kullanarak sunucu tarafından Ajax'a bakın ve dinamik Web uygulaması deneyimleri
oluşturmak için çığır açan bir yaklaşımla tanışın (developerWorks, Eylül 2005).

• "Ajax for Java developers: Java object serialization for Ajax:" Java nesnesi
diziselleştirmesine ilişkin beş yaklaşımı inceleyin ve ağ üzerinden nesneleri nasıl
göndereceğinizi ve Ajax ile nasıl etkileşime geçeceğinizi öğrenin (developerWorks,
Ekim 2005).

• "Call SOAP Web services with Ajax, Part 1: Build the Web services client:" Ajax'ın
var olan SOAP tabanlı Web hizmetleriyle bütünleştirilmesine ilişkin bu ileri düzey
makaleyi inceleyin; Ajax tasarım şablonunu kullanarak Web tarayıcısı tabanlı SOAP
Web hizmetleri istemcisini nasıl uygulayacağınızı gösterir (developerWorks, Ekim
2005).

• "Ajax: A New Approach to Web Applications": Ajax moniker teriminin ilk kez
kullanıldığı bu makaleyi okuyun -- tüm Ajax geliştiricileri bu makaleyi okumalıdır.

• HTTP durum kodları: W3C'den alınan durum kodlarının tam listesini gözden geçirin.

• Head Rush Ajax, Elisabeth Freeman, Eric Freeman ve Brett McLaughlin (Şubat 2006,
O'Reilly Media, Inc.): Bu makaledeki fikirleri beyninize Head First yöntemiyle
yükleyin.

• Java and XML, İkinci Basım, Brett McLaughlin (Ağustos 2001, O'Reilly Media, Inc.):
Yazarın, XHTML ve XML dönüşümleriyle ilgili düşüncelerini okuyun.

• JavaScript: The Definitive Guide, David Flanagan (Kasım 2001, O'Reilly Media,
Inc.): JavaScript ve dinamik Web sayfalarıyla çalışmaya ilişkin kapsamlı yönergeleri
inceleyin. Yayınlanacak olan yeni basımda Ajax ile ilgili iki yeni bölüm vardır.

• Head First HTML with CSS & XHTML, Elizabeth ve Eric Freeman (Aralık 2005,
O'Reilly Media, Inc.): XHTML, CSS ve bu ikisini birlikte kullanmayı öğrenmeyle
ilgili bu eksiksiz kaynağı dikkatle okuyun.

• developerWorks Web mimarisi alanı: Web oluşturma becerilerinizi genişletin.

• developerWorks teknik etkinlikleri ve Web yayınları: Teknik geliştiricilere yönelik bu


yazılım brifinglerini takip edin.

Ürün ve teknoloji edinme


IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki
geliştirme projenizi oluşturun.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 69/129


Ajax'ta Uzmanlaşma, Bölüm 5:
DOM'nin kullanılması
Web sayfalarınızı hızla güncellemek için JavaScript kullanın

Düzey: Başlangıç

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

11 Nisan 2006

Geçen ay Brett, öğeleri sahne arkasında Web sayfalarınızı tanımlamak için çalışan Belge
Nesne Modeli'ni tanıtmıştı. Bu ay, DOM ile ilgili daha derin konulara giriyor. DOM ağacının
paçalarını nasıl yaratabileceğinizi, kaldırabileceğinizi ve değiştirebileceğinizi öğrenin ve Web
sayfalarınızı hızla güncellemek için sonraki adımı atın!

Bu dizide geçen ay yayınlanan yazımı okuduysanız, bir Web tarayıcısı Web sayfalarınızdan
birini görüntülediğinde neler olup bittiğini birinci elden öğrenmişsinizdir. O yazımda da
anlattığım gibi, sayfanız için tanımladığınız HTML ve CSS bir Web tarayıcısına
gönderildiğinde, metinden bir nesne modeline çevrilir. Kodun basit ya da karmaşık
olmasından, tümünün bir dosyada ya da ayrı dosyalarda saklanmasından bağımsız olarak bu
geçerlidir. Daha sonra tarayıcı, sağladığınız metin dosyalarıyla çalışmak yerine, doğrudan
nesne modeliyle çalışır. Tarayıcının kullandığı modele Belge Nesne Modeli denir.
Belgelerinizdeki öğeleri, öznitelikleri ve metni temsil eden nesneleri bir birine bağlar. HTML
ve CSS içindeki tüm stiller, değerler ve hatta boşlukların çoğu nesne modelinde birleştirilir.
Belirli bir Web sayfasına ilişkin özel modele, sayfanın DOM ağacı denir.

Bir DOM ağacının ne olduğunu anlamak ve HTML'nizi ve CSS'nizi nasıl gösterdiğini bilmek,
Web sayfalarınızın denetimini almak konusunda atacağınız ilk adımdır. Daha sonra, belirli bir
Web sayfası için DOM ağacıyla nasıl çalışacağınızı öğrenmeniz gerekir. Örneğin, DOM
ağacına bir öğe eklerseniz, bu öğe hemen kullanıcının Web tarayıcısında görüntülenir --
sayfanın yeniden yüklenmesine gerek yoktur. DOM ağacından metnin bir kısmını
kaldırdığınızda da metin, kullanıcının ekranından kaybolur. Kullanıcı arabirimini DOM
aracılığıyla değiştirebilir ve kullanıcı arabirimiyle DOM üzerinden etkileşime geçebilirsiniz;
bu da size programlama konusunda inanılmaz bir güç ve esneklik sağlar. DOM ağacıyla nasıl
çalışılacağını öğrendiğinizde, zengin içerikli, etkileşimli, dinamik Web sitelerine doğru büyük
bir adım atarsınız.

Aşağıdaki konular geçen ayki "Web yanıtı için DOM'yi kullanma" yazısını temel alır; o
makaleyi henüz okumadıysanız, buradan ileri gitmeden önce okumak isteyebilirsiniz.

Kısaltmalarda telaffuz önemlidir

Birçok açıdan Belge Nesne Modeli'ne, çok

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 70/129


daha kolay bir şekilde Belge Düğüm
Modeli denilebilirdi. Elbette, insanların
çoğu düğüm teriminin anlamını bilmediği
ve "DNM"nin, "DOM" kadar kolay
söylenemediği için W3C'nin neden DOM
kısaltmasını seçtiğini anlamak çok da zor
değil.

Çeşitli tarayıcılar ve dillerle kullanılabilir

Belge Nesne Modeli, bir W3C standardıdır (W3C bağlantıları için Kaynaklar bölümüne
bakın). Bu nedenle, tüm modern Web tarayıcıları DOM'yi, en azından belirli bir düzeye kadar
destekler. Tarayıcılar arasında bazı farklılıklar vardır, ancak temel DOM işlevselliğini
kullanırsanız -- ve birkaç özel ve olağandışı duruma dikkat ederseniz -- DOM kodunuz tüm
tarayıcılarda aynı şekilde çalışacaktır. Opera içindeki bir Web sayfasını değiştirmek için
yazdığınız kod, Apple's Safari®, Firefox®, Microsoft® Internet Explorer® ve Mozilla®
tarayıcılarında da çalışır.

DOM'yi aynı zamanda yaygın olarak kullanılan programlama dillerinin çoğuyla birlikte
kullanabilirsiniz. W3C, DOM için birkaç dil ilişkilendirmesi tanımlamıştır. Dil
ilişkilendirmesi, basit anlamda, DOM'yi belirli bir dille kullanabilmeniz için tanımlanan bir
API'dir. Örneğin, C, Java ve JavaScript için iyi tanımlanmış DOM dil ilişkilendirmeleri
bulabilirsiniz. Dolayısıyla, DOM'yi bu dillerin herhangi biriyle kullanabilirsiniz. Dil
ilişkilendirmeleri, diğer bazı diller için de mevcuttur, ancak bunların çoğu W3C tarafından
değil, üçüncü taraflar tarafından tanımlanmıştır.

Bu dizide, DOM ile JavaScript ilişkilendirmeleri konusuna odaklanacağım. Çoğu


zamanuyumsuz uygulama geliştirme Web tarayıcısında çalıştırılmak üzere JavaScript
kodunda yazıldığı için bu oldukça anlamlıdır. JavaScript ve DOM ile kullanıcı arabirimini
hızla değiştirebilir, kullanıcı olaylarına ve girişlerine yanıt verebilir ve daha birçok işlem
yapabilirsiniz -- tüm bunları oldukça standartlaşmış JavaScript'i kullanarak gerçekleştirirsiniz.

Tüm bunlar söylendikten sonra, diğer dillerdeki DOM dil ilişkilendirmelerine debakmanızı
öneririm. Örneğin, Java dili ilişkilendirmelerini yalnızca HTML ile değil, aynı zamanda bu
makalenin sonraki kısımlarında da anlatacağım gibi, XML ile de çalışmak için
kullanabilirsiniz. Burada öğreneceğiniz dersler HTML'in ötesinde, yalnızca istemci tarafı
JavaScript'inden çok daha fazla ortam için geçerlidir.

Kavramsal düğüm

Düğüm, DOM içindeki en temel nesne tipidir. Aslında, bu makalenin sonraki kısımlarında da
göreceğiniz gibi, DOM ile tanımlanan neredeyse her nesne düğüm nesnesini genişletir.
Ancak, semantikle ilgili daha ileri aşamalara geçmeden önce, bir düğümün temsil ettiği
kavramı anlamanız gerekir; daha sonra, düğümün gerçek özelliklerini ve yöntemlerini
öğrenmek sizin için çok kolay olacaktır.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 71/129


Bir DOM ağacında, karşılaşacağınız hemen hemen her şey bir düğümdür. DOM ağacındaki
her öğe, en temel düzeyinde bir düğümdür. Her öznitelik bir düğümdür. Her metin parçası bir
düğümdür. Açıklamalar, özel karakterler (telif hakkı simgesini temsil eden &copy; gibi) ve
DOCTYPE bildirimi (HTML ya da XHTML'nizde varsa) bile birer düğümdür. Bu tiplerin
ayrı ayrı özelliklerine girmeden önce, düğümün ne anlama geldiğini gerçekten kavramanız
gerekir.

Düğüm bir...

En basit anlatımla düğüm, bir DOM ağacındaki tek bir şeydir. "Şey" sözcüğü, belirsizliği
nedeniyle özellikle kullanılmıştır, çünkü bu olabilecek en belirgin terimdir. Örneğin,
HTML'nizdeki bir öğe (img gibi) ile HTML'nizdeki bir metin parçasının ("Scroll down for
more details" gibi) birçok ortak özelliğe sahip oldukları yeterince açık olmayabilir. Ancak
bunun nedeni, bu ayrı tiplere işlevleri açısından bakmanız ve birbirlerinden ne kadar farklı
olduklarını düşünmenizdir.

Bunun yerine, DOM ağacındaki her bir öğenin ve metin parçasının bir üst öğesinin olduğunu;
bu üst öğenin de, başka bir öğenin alt öğesi (img öğesinin p öğesine yerleştirilmesi gibi) ya da
DOM ağacındaki en üst öğe olduğunu (her belge için bir defalık özel bir durumdur ve html
öğesini kullandığınız yerdir) düşünün. Ayrıca, hem öğelerin hem de metnin bir tipinin
olduğunu dikkate alın. Bir öğeye ilişkin tip, gayet açık olarak öğedir; metne ilişkin tip de
metindir. Her bir düğümün oldukça iyi tanımlanmış bir yapısı da vardır: kendi altında, alt
öğeler gibi düğümleri var mı? Kardeş düğümleri (öğe ya da metnin "yanındaki" düğümler)
var mı? Her bir düğüm hangi belgeye ait?

Açıkçası, bunların çoğu oldukça soyut görünür. Aslında, bir öğe tipinin öğe olduğunu
söylemek biraz saçma görünebilir. Ancak, ortak bir nesne tipi olarak düğümün sahip olduğu
değeri anlamanız için biraz soyut düşünmeniz gerekir.

Ortak düğüm tipi

DOM kodunuzun içinde en çok gerçekleştireceğiniz tek görev bir sayfanın DOM ağacında
gezinmek olacaktır. Örneğin, "id" özniteliğine göre bir formu bulabilir ve bu formun içindeki
iç içe geçmiş öğelerle ve metinle çalışmaya başlayabilirsiniz. Metin yönergeleri, giriş
alanlarına ilişkin etiketler, gerçek inputöğeleri ve büyük olasılıkla diğer HTML öğeleri (img
öğeleri gibi) ve bağlantılar (a öğeleri) olacaktır. Öğeler ve metin tamamen farklı tiplerdeyse,
bir tipten diğerine geçmek için tamamen farklı kod parçaları yazmanız gerekir.

Bir ortak düğüm tipi kullanırsanız her şey farklılaşır. Böyle bir durumda, basit bir şekilde
düğümden düğüme geçer ve düğümün tipiyle, yalnızca bir öğe ya da metinle ilgili özel bir şey
yapmak istediğinizde ilgilenirsiniz. DOM ağacında dolaşırken, bir öğenin üst öğesine -- ya da
alt öğelerine -- geçmek için, diğer düğüm tiplerinde gerçekleştireceğiniz işlemleri
kullanırsınız. Bir düğüm tipiyle, yalnızca belirli bir düğüm tipine özgü (öğenin öznitelikleri
gibi) bir şeyler yapmanız gerektiğinde özel olarak çalışmanız gerekir. DOM ağacındaki her
bir nesneyi bir düğüm olarak düşünmek, çalışmanızı çok basitleştirir. Aklınızdan bunu
çıkarmadan, bir sonraki bölümde, özellikler ve yöntemlerden başlayarak DOM Düğüm
yapısının tam olarak neler sunduğuna bakacağım.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 72/129


Düğüm özellikleri

DOM düğümleriyle çalışırken bazı özellikleri ve yöntemleri kullanmak isteyeceksiniz; o


zaman önce bunları gözden geçirelim. Bir DOM düğümünün temel özellikleri şunlardır:

• nodeName, düğümün adını bildirir (ek bilgi için aşağıya bakın).


• nodeValue, düğümün "değerini" verir (ek bilgi için aşağıya bakın).
• parentNode, düğümün üst öğesini verir. Her öğenin, özniteliğin ve metnin bir üst
öğesinin olduğunu unutmayın.
• childNodes, bir düğümün alt öğelerinin listesidir. HTML ile çalışırken, bu liste
yalnızca bir öğe üzerinde çalışırken işe yarar; metin düğümlerinin ve öznitelik
düğümlerinin alt düğümleri yoktur.
• firstChild, childNodes listesindeki birinci düğüme giden bir kısayoldur.
• lastChild, childNodes listesindeki son düğüme giden bir kısayoldur.
• previousSibling, geçerli düğümden önceki düğümü verir. Diğer bir deyişle, bu
düğümün üst öğesinin childNodes listesinde, geçerli düğümden bir önceki düğümü
verir (kafanız karıştıysa, son cümleyi yeniden okuyun).
• nextSibling, previousSibling özelliğine benzer; üst öğenin childNodes
listesindeki bir sonraki düğümü verir.
• attributes, yalnızca bir öğe düğümünde yararlı olur; bir öğenin özniteliklerinin
listesini verir.

Diğer birkaç özellik, daha soysal XML belgeleri için geçerlidir ve HTML tabanlı Web
sayfalarıyla çalıştığınızda pek de işinize yaramazlar.

Alışılmadık özellikler

nodeName ve nodeValue özelliklerinin dışında, yukarıda tanımlanan özelliklerin çoğu kendi


kendini anlatmaktadır. Bu özellikleri yalnızca açıklamak yerine birkaç garip soruyu düşünün:
Bir metin düğümü için nodeName (düğümAdı) değeri ne olurdu? Benzer bir şekilde, Bir öğeye
ilişkin nodeValue (düğümDeğeri) ne olurdu?

Bu sorular sizi şaşırttıysa, bu özelliklerin doğasında varolan karışıklık olasılığını da


anlamışsınızdır. nodeName ve nodeValue, gerçekte tüm düğüm tipleri için geçerli değildir (bu,
bir düğümdeki diğer özelliklerin birkaçı için de geçerlidir). Bu, bir anahtar kavramı da
şekillendirir: Bu değerlerin herhangi biri boş bir değer verebilir (bazen JavaScript içinde
"undefined" [tanımlanmamış] olarak görünür). Örneğin, bir metin düğümüne ilişkin nodeName
özelliği boş bir değerdir (ya da bazı tarayıcılarda metin düğümlerinin bir adı olmadığı için
"undefined" [tanımlanmamış] olur). nodeValue, bekleyeceğiniz üzere düğümün metnini
döndürür.

Benzer şekilde, öğelerin bir nodeName özelliği vardır (öğenin adı), ancak bir öğe nodeValue
özelliğinin değeri her zaman boştur. Özniteliklerin, hem nodeName hem de nodeValue
özellikleri için değerleri vardır. Bir sonraki bölümde bu ayrı tiplerle ilgili biraz daha ayrıntıya
gireceğim, ancak bu özellikler her düğümün parçası olduğu için, burada bunlardan söz
etmekte fayda var.

Şimdi, çalışan düğüm özelliklerinin birkaçını gösteren Liste 1'e bakın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 73/129


Liste 1. DOM içinde düğüm özelliklerinin kullanılması
// These first two lines get the DOM tree for the current Web page,
// and then the <html> element for that DOM tree
var myDocument = document;
var htmlElement = myDocument.documentElement;

// What's the name of the <html> element? "html"


alert("The root element of the page is " + htmlElement.nodeName);

// Look for the <head> element


var headElement = htmlElement.getElementsByTagName("head")[0];
if (headElement != null) {
alert("We found the head element, named " + headElement.nodeName);
// Print out the title of the page
var titleElement = headElement.getElementsByTagName("title")[0];
if (titleElement != null) {
// The text will be the first child node of the <title> element
var titleText = titleElement.firstChild;
// We can get the text of the text node with nodeValue
alert("The page title is '" + titleText.nodeValue + "'");
}

// After <head> is <body>

var bodyElement = headElement.nextSibling;


while (bodyElement.nodeName.toLowerCase() != "body") {
bodyElement = bodyElement.nextSibling;
}

// We found the <body> element...

// We'll do more when we know some methods on the nodes.


}

Düğüm yöntemleri

Sırada tüm düğümlerle kullanılabilen yöntemler var (düğüm özelliklerinde olduğu gibi, çoğu
HTML DOM işlemleri için gerçekten geçerli olmayan birkaç yöntemi atladım):

• insertBefore(newChild, referenceNode), referenceNode değerinden önce


newChild düğümünü yerleştirir. Bu kodu, istediğiniz newChild düğümünün üst
öğesinde çağıracağınızı unutmayın.
• replaceChild(newChild, oldChild), oldChild düğümünü newChild düğümüyle
değiştirir.
• removeChild(oldChild), işlevin çalıştırıldığı düğümden oldChild düğümünü
kaldırır.
• appendChild(newChild), bu işlevin çalıştırıldığı düğüme newChild düğümünü ekler.
newChild, hedef düğümün alt öğelerinin sonuna eklenir.
• hasChildNodes(), çağrıldığı düğümün alt öğeleri varsa doğru, yoksa yanlış değerini
döndürür.
• hasAttributes(), çağrıldığı düğümün öznitelikleri varsa doğru, özniteliği yoksa
yanlış değerini döndürür.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 74/129


Çoğu bölümde, bu yöntemlerin tümünün, büyük ölçüde bir düğümün alt öğeleriyle ilgili
olduğunu fark etmişsinizdir. Bu, onların birincil amacıdır. Yalnızca bir metin düğümünün
değerini ya da bir öğenin adını kavramaya çalışıyorsanız, basit bir şekilde düğümün
özelliklerini kullanabileceğiniz için yöntemleri çok sık çağırmazsınız. Liste 2, yukarıdaki
yöntemlerin bazılarını kullanarak Liste 1'deki kod üzerine kurulur.

Liste 2. DOM içinde düğüm yöntemlerinin kullanılması


// These first two lines get the DOM tree for the current Web page,
// and then the <html> element for that DOM tree
var myDocument = document;
var htmlElement = myDocument.documentElement;

// What's the name of the <html> element? "html"


alert("The root element of the page is " + htmlElement.nodeName);

// Look for the <head> element


var headElement = htmlElement.getElementsByTagName("head")[0];
if (headElement != null) {
alert("We found the head element, named " + headElement.nodeName);
// Print out the title of the page
var titleElement = headElement.getElementsByTagName("title")[0];
if (titleElement != null) {
// The text will be the first child node of the <title> element
var titleText = titleElement.firstChild;
// We can get the text of the text node with nodeValue
alert("The page title is '" + titleText.nodeValue + "'");
}

// After <head> is <body>

var bodyElement = headElement.nextSibling;


while (bodyElement.nodeName.toLowerCase() != "body") {
bodyElement = bodyElement.nextSibling;
}

// We found the <body> element...

// Remove all the top-level <img> elements in the body


if (bodyElement.hasChildNodes()) {
for (i=0; i<bodyElement.childNodes.length; i++) {
var currentNode = bodyElement.childNodes[i];
if (currentNode.nodeName.toLowerCase() == "img") {
bodyElement.removeChild(currentNode);
}
}
}
}

Beni sına!

Şimdiye kadar Liste 1 ve 2'de yalnızca iki örnek gördünüz, ancak bunlar bile DOM ağacını
kullanmaya başladığınızda yapabileceklerinize ilişkin her tür fikri vermiş olmalı. Buraya

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 75/129


kadar gösterildiği biçimde kodu denemek isterseniz, Liste 3'ü bir HTML dosyasına aktarın,
kaydedin ve Web tarayıcınıza yükleyin.

Liste 3. DOM'nin kullanıldığı bazı JavaScript kodlarının bulunduğu bir HTML dosyası
<html>
<head>
<title>JavaScript and the DOM</title>
<script language="JavaScript">
function test() {
// These first two lines get the DOM tree for the current Web page,
// and then the <html> element for that DOM tree
var myDocument = document;
var htmlElement = myDocument.documentElement;

// What's the name of the <html> element? "html"


alert("The root element of the page is " + htmlElement.nodeName);

// Look for the <head> element


var headElement = htmlElement.getElementsByTagName("head")[0];
if (headElement != null) {
alert("We found the head element, named " + headElement.nodeName);
// Print out the title of the page
var titleElement = headElement.getElementsByTagName("title")[0];
if (titleElement != null) {
// The text will be the first child node of the <title> element
var titleText = titleElement.firstChild;
// We can get the text of the text node with nodeValue
alert("The page title is '" + titleText.nodeValue + "'");
}

// After <head> is <body>

var bodyElement = headElement.nextSibling;


while (bodyElement.nodeName.toLowerCase() != "body") {
bodyElement = bodyElement.nextSibling;
}

// We found the <body> element...

// Remove all the top-level <img> elements in the body


if (bodyElement.hasChildNodes()) {
for (i=0; i<bodyElement.childNodes.length; i++) {
var currentNode = bodyElement.childNodes[i];
if (currentNode.nodeName.toLowerCase() == "img") {
bodyElement.removeChild(currentNode);
}
}
}
}
}
</script>
</head>
<body>

<p>JavaScript and DOM are a perfect match.


You can read more in <i>Head Rush Ajax</i>.</p>
<img src="http://www.headfirstlabs.com/Images/hraj_cover-150.jpg" />

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 76/129


<input type="button" value="Test me!" onClick="test();" />
</body>

</html>

Bu sayfayı tarayıcınıza yüklediğinizde, Şekil 1'dekine benzer bir sayfa görmeniz gerekir.

Şekil 1. JavaScript çalıştırmak üzere bir düğmesi olan basit bir HTML sayfası

Test me! (Beni sına!) düğmesini tıklattığınızda Şekil 2'deki gibi uyarı kutuları
görüntülenmeye başlar.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 77/129


Şekil 2. nodeValue değeri kullanılarak, bir öğenin adını gösteren uyarı kutuları

Kod çalışmayı tamamladığında, resimler Şekil 3'te gösterildiği gibi gerçek zamanlı olarak
sayfadan kaldırılır.

Şekil 3. JavaScript kullanılarak, gerçek zamanlı olarak kaldırılan resimler

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 78/129


API tasarım notları

Her bir düğümdeki kullanılabilir özelliklere ve yöntemlere yeniden bakın. Bunlar, nesne
odaklı (OO) programlama kullananlar için DOM'ye ilişkin bir temel noktayı açıklar: DOM
çok da nesne odaklı bir API değildir. Birincisi, birçok durumda bir düğüm nesnesinde yöntem
çağırmak yerine, nesnenin özelliklerini doğrudan kullanırsınız. getNodeName() yöntemi
yoktur; örneğin, nodeName özelliğini doğrudan kullanırsınız. Dolayısıyla düğüm nesneleri (ve
diğer DOM nesneleri), özellikleri aracılığıyla, yalnızca işlevleri değil, birçok veriyi de
gösterir.

İkincisi, özellikle Java ya da C++ gibi dillerde aşırı yüklü nesnelerle ve nesne odaklı API'lerle
çalışmaya alıştıysanız, DOM içindeki nesnelerin ve yöntemlerin adlandırılması biraz garip
görünebilir. DOM'nin, birkaç dil belirtmek gerekirse, C, Java ve JavaScript içinde çalışması
gerekir; bu yüzden, API tasarımından bazı ödünler verilmiştir. Örneğin, aşağıdaki gibi
görünen NamedNodeMap yöntemlerinde iki farklı yöntem görürsünüz:

• getNamedItem(String name)
• getNamedItemNS(Node node)

OO programcıları için bu oldukça garip görünür. İki yöntemin amacı aynıdır, ancak biri bir
dizeyi (String) alırken, diğeri bir düğümü (Node) alır. OO API'lerinin çoğunda, her iki sürüm
için de aynı yöntem adını kullanırdınız. Kodunuzu çalıştıran sanal makine, yönteme geçirilen
nesne tipine dayalı olarak çalıştırılacak yöntemi belirlerdi.

Buradaki sorun, JavaScript'in yöntem aşırı yüklemesi adı verilen bu tekniği


desteklememesidir. Diğer bir deyişle, JavaScript belirli bir adda tek bir yöntem ya da işlevin
olmasına izin verir. Bir dizeyi alan getNamedItem() adlı bir yönteminiz varsa, ikinci sürüm
farklı tipte bir bağımsız değişken (ya da tamamen farklı bir bağımsız değişkenler kümesi) alsa
bile getNamedItem() adlı başka bir yönteminiz ya da işleviniz olamaz. Bunu yaparsanız
JavaScript bir hata bildirir ve kodunuz, çalışmasını beklediğiniz gibi çalışmaz.

Özünde, DOM bilinçli olarak yöntem aşırı yüklemesinden ve diğer OO programlama


tekniklerinden kaçınır. Bunu, API'nin OO programlama tekniklerini desteklemeyenler de
dahil olmak üzere birden çok dil üzerinde çalıştığından emin olmak için yapar. Sonuçta
fazladan birkaç yöntem adı öğrenmeniz gerekir. İyi tarafı da DOM'yi herhangi bir dilde
öğrenebileceğiniz -- Java gibi -- ve aynı yöntem adlarının ve kodlama yapısının DOM
uygulaması olan diğer dillerde de -- JavaScript gibi -- çalışacağını bilmektir.

Programcılar dikkat etsin

API tasarımıyla uğraşıyorsanız -- ya da yalnızca yakından ilgileniyorsanız -- bir şeyi merak


edebilirsiniz: "Düğüm tipine ilişkin özellikler neden tüm düğümler için ortak değil?" Bu güzel
bir sorudur ve yanıtı, teknik nedenlerden çok politika ve karar almayla ilgilidir. Kısacası,
yanıt "Kim bilir! Ama bu biraz can sıkıcı, değil mi?" olur.

nodeName özelliği her tipin bir adı olması için tasarlanmıştır; ancak birçok durumda, ad
tanımlanmamıştır ya da programcılar için değer taşımayan garip bir iç addır (örneğin, Java'da
bir metin düğümünün nodeName özelliği, birçok durumda "#text" olarak bildirilir). Aslında,
hata işlemenin size bırakıldığını varsaymanız gerekir. Hemen myNode.nodeName değerine
erişmek ve bu değeri kullanmak güvenli değildir; birçok durumda, değer boş olacaktır. Bu

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 79/129


yüzden, programlama söz konusu olduğunda bu durumlarda programcıların dikkat etmesi
gerekir.

Ortak düğüm tipleri

Bir DOM düğümünün belirleyici niteliklerinin ve özelliklerinin bazılarını (ve bazı


garipliklerini) gördüğünüze göre, birlikte çalışacağınız düğümlerin belirli tiplerinden
bazılarıyla ilgili bilgileri öğrenmeye hazırsınız demektir. Web uygulamalarının çoğunda,
yalnızca dört düğüm tipiyle çalışırsınız:

• Belge düğümü, tüm HTML belgesini belirtir.


• Öğe düğümleri, a ya da img gibi HTML öğelerini belirtir.
• Öznitelik düğümleri, HTML öğelerindeki href (a öğesinde) ya da src (img
öğesinde) gibi öznitelikleri gösterir.
• Metin düğümleri, HTML belgesindeki "Click on the link below for a complete set
list" gibi metinleri belirtir. Bu, p, a ya da h2 gibi öğelerin içinde görünen metindir.

HTML ile uğraşırken, zamanınızın yaklaşık %95'ini bu düğüm tipleriyle çalışarak geçirirsiniz.
Bu nedenle, bu ayki makalenin geri kalan kısmını bu konuda daha ayrıntılı bilgi vermek için
kullanacağım. (İleride yazacağım bir makalede XML konusunu anlatırken, diğer düğüm
tiplerinden bazılarını da tanıtacağım.)

Belge düğümü

Birinci düğüm tipi, yazdığınız DOM tabanlı hemen her kodda kullanacağınız belge
düğümüdür. Belge düğümü, aslında HTML (ya da XML) sayfasının bir öğesi değil, sayfanın
kendisidir. Dolayısıyla HTML Web sayfasında, belge düğümü tüm DOM ağacıdır.
JavaScript'te, document anahtar sözcüğünü kullanarak belge düğümüne erişebilirsiniz:

// These first two lines get the DOM tree for the current Web page,
// and then the <html> element for that DOM tree
var myDocument = document;
var htmlElement = myDocument.documentElement;

JavaScript'teki document anahtar sözcüğü, geçerli Web sayfasına ilişkin DOM ağacını
gösterir. Buradan, ağaçtaki tüm düğümlerle çalışabilirsiniz.

Aşağıdaki yöntemlere benzer yöntemleri kullanarak yeni düğümler yaratmak için document
belgesini de kullanabilirsiniz:

• createElement(elementName), sağlanan adla bir öğe oluşturur.


• createTextNode(text), sağlanan metinle yeni bir metin düğümü oluşturur.
• createAttribute(attributeName), sağlanan adla yeni bir öznitelik oluşturur.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 80/129


Dikkat edilmesi gereken temel nokta, bu yöntemlerin düğümleri yarattığı, ancak bunları
herhangi bir belirli belgeye bağlamadığı ya da yerleştirmediğidir. Bunun için,
insertBefore() ya da appendChild() gibi önceden gördüğünüz yöntemlerden birini
kullanmanız gerekir. Aşağıdakine benzer bir kod kullanarak yeni bir öğe oluşturabilir ve
bunu, bir belgeye ekleyebilirsiniz:

var pElement = myDocument.createElement("p");


var text = myDocument.createTextNode("Here's some text in a p element.");
pElement.appendChild(text);
bodyElement.appendChild(pElement);

Bir Web sayfasının DOM ağacına erişmek için document öğesini kullandıktan sonra, öğelerle,
özniteliklerle ve metinle doğrudan çalışmaya başlayabilirsiniz.

Öğe düğümleri

Öğe düğümleriyle çok çalışacaksınız, ancak öğeler üzerinde gerçekleştirmeniz gereken birçok
işlem, yalnızca öğelere özel yöntemler ve özellikler yerine, tüm düğümler için geçerli
yöntemleri ve özellikleri içerir. Yalnızca iki yöntem takımı öğelere özeldir:

1. Özniteliklerle çalışmaya ilişkin yöntemler:


o getAttribute(name), name adlı özniteliğin değerini döndürür.
o removeAttribute(name), name adlı özniteliği kaldırır.
o setAttribute(name, value), name adlı bir öznitelik oluşturur ve değerini
value değerine ayarlar.
o getAttributeNode(name), name adlı öznitelik düğümünü verir (öznitelik
düğümleri aşağıda ele alınmıştır).
o removeAttributeNode(node), sağlanan düğümle eşleşen öznitelik düğümünü
kaldırır.
2. İç içe geçmiş öğeleri bulmaya ilişkin yöntemler:
o getElementsByTagName(elementName), sağlanan adın bulunduğu öğe
düğümleri listesini verir.

Bunların tümü büyük ölçüde kendi kendilerini açıklar niteliktedir, ancak yine de aşağıdaki
örneklere bakmanızda yarar vardır.

Özniteliklerle çalışma

Özniteliklerle çalışmak oldukça kolaydır; örneğin, document nesnesiyle ve öğesiyle ve


yukarıdaki yöntemlerin bazılarıyla yeni bir img öğesi oluşturabilirsiniz:

var imgElement = document.createElement("img");


imgElement.setAttribute("src",
"http://www.headfirstlabs.com/Images/hraj_cover-150.jpg");
imgElement.setAttribute("width", "130");
imgElement.setAttribute("height", "150");
bodyElement.appendChild(imgElement);

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 81/129


Bu, şimdiye kadar oldukça rutin görünmüş olabilir. Aslında, bir düğüm kavramını anlamaya
başladıktan ve kullanılabilir yöntemleri bildikten sonra Web sayfalarınızda ve JavaScript
kodunuzda DOM ile çalışmanın basit olduğunu görmeye başlamanız gerekir. Yukarıdaki
kodda, JavaScript yeni bir img öğesi oluşturur, bazı öznitelikleri ayarlar ve bunu daha sonra
HTML sayfasının gövdesine ekler.

İç içe geçmiş öğelerin bulunması

İç içe geçmiş öğeleri bulmak da kolaydır. Örneğin, Liste 3'teki HTML sayfasında bulunan
tüm img öğelerini bulmak ve kaldırmak için aşağıdaki kodu kullandım:

// Remove all the top-level <img> elements in the body


if (bodyElement.hasChildNodes()) {
for (i=0; i<bodyElement.childNodes.length; i++) {
var currentNode = bodyElement.childNodes[i];
if (currentNode.nodeName.toLowerCase() == "img") {
bodyElement.removeChild(currentNode);
}
}
}

getElementsByTagName() yöntemini kullanarak da benzer bir etki elde edebilirdiniz:

// Remove all the top-level <img> elements in the body


var imgElements = bodyElement.getElementsByTagName("img");

for (i=0; i<imgElements.length; i++) {


var imgElement = imgElements.item[i];
bodyElement.removeChild(imgElement);
}

Öznitelik düğümleri

DOM, öznitelikleri düğüm olarak gösterir ve bir öğenin attributes özelliğini kullanarak her
zaman bir öğenin özniteliklerini aşağıda gösterildiği gibi alabilirsiniz:

// Remove all the top-level <img> elements in the body


var imgElements = bodyElement.getElementsByTagName("img");

for (i=0; i<imgElements.length; i++) {


var imgElement = imgElements.item[i];

// Print out some information about this element


var msg = "Found an img element!";
var atts = imgElement.attributes;
for (j=0; j<atts.length; j++) {
var att = atts.item(j);
msg = msg + "\n " + att.nodeName + ": '" + att.nodeValue + "'";

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 82/129


}
alert(msg);

bodyElement.removeChild(imgElement);
}

Özniteliklerin garip durumu

DOM söz konusu olduğunda, özniteliklerin


biraz özel bir durumu vardır. Bir yandan,
öznitelikler diğer öğeler ya da metinler
gibi, gerçekte öğelerin alt öğeleri değildir;
diğer bir deyişle bir öğenin "altında"
görünmezler. Aynı zamanda, bir öğeyle
kesinlikle bir ilişkileri vardır; bir öğe
özniteliklere "sahiptir". DOM, öznitelikleri
göstermek için düğümleri kullanır ve
bunları özel bir listeyle bir öğe üzerinde
kullanımına sunar. Bu nedenle, öznitelikler
DOM ağacının bir parçasıdır, ancak
genellikle ağaçta görünmezler.
Özniteliklerin, DOM ağacı yapısının geri
kalanıyla olan ilişkisinin biraz belirsiz
olduğunu söylemek yeterlidir.

attributes özelliğinin aslında düğüm tipi üzerinde olduğunu ve özellikle öğe tipi üzerinde
olmadığını belirtelim. Bu biraz gariptir ve kodlamanızı etkilemez, ancak bilinmesi yararlıdır.

Öznitelik düğümleriyle çalışmak kesinlikle mümkündür, ancak özniteliklerle çalışmak için


öğede bulunan yöntemlerin kullanılması genellikle daha kolay olur. Yöntemler aşağıdaki
gibidir:

• getAttribute(name), name adlı özniteliğin değerini döndürür.


• removeAttribute(name), name adlı özniteliği kaldırır.
• setAttribute(name, value), name adlı bir öznitelik oluşturur ve değerini value
değerine ayarlar.

Bu üç yöntem, öznitelik düğümleriyle doğrudan çalışmayı gerektirmez. Bunun yerine,


öznitelikleri ve değerlerini yalnızca basit dize özellikleriyle ayarlayabilir ve kaldırabilirsiniz.

Metin düğümleri

Düşünmeniz gereken son düğüm tipi -- en azından HTML DOM ağaçlarıyla çalışırken --
metin düğümleridir. Metin düğümleriyle çalışmak için yaygın olarak kullanacağınız
özelliklerin neredeyse tümü, gerçekte düğüm nesnesinde bulunur. Aslında, aşağıda
gösterildiği gibi metin düğümünden metin almak için genellikle nodeValue özelliğini
kullanacaksınız:

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 83/129


var pElements = bodyElement.getElementsByTagName("p");
for (i=0; i<pElements.length; i++) {
var pElement = pElements.item(i);
var text = pElement.firstChild.nodeValue;
alert(text);
}

Diğer birkaç yöntem, metin düğümlerine özeldir. Bunlar, bir düğümdeki verilere ekleme
yapma ya da verileri bölmeyle uğraşırlar:

• appendData(text), sağladığınız metni, metin düğümünün var olan metninin sonuna


ekler.
• insertData(position, text), metin düğümünün ortasına veri yerleştirmenizi
sağlar. Sağladığınız metni, belirtilen konuma yerleştirir.
• replaceData(position, length, text), belirtilen konumdan başlayarak, belirtilen
uzunlukta karakterleri kaldırır ve yönteme sağladığınız metni kaldırılan metnin yerine
yerleştirir.

Hangi düğüm tipi?

Şimdiye kadar gördüklerinizin çoğu, çalıştığınız düğüm tipini bildiğiniz varsayımına dayanır,
ancak durum her zaman böyle değildir. Örneğin, bir DOM ağacında geziniyorsanız ve ortak
düğüm tipleriyle çalışıyorsanız, bir öğeye ya da metne geçtiğinizi fark etmeyebilirsiniz. Bir p
öğesinin tüm alt öğelerini alabilir ve metinle mi, bir b öğesiyle mi, yoksa bir img öğesiyle mi
çalıştığınızdan emin olamayabilirsiniz. Böyle durumlarda, bir düğümle çalışmaya başlamadan
önce ne tip bir düğümle çalıştığınızı anlamanız gerekecektir.

Neyse ki bunu anlamak oldukça basittir. DOM düğüm tipi, aşağıdakilere benzer birkaç
değişmez değeri tanımlar:

1. Node.ELEMENT_NODE, öğe düğüm tipine ilişkin değişmezdir.


2. Node.ATTRIBUTE_NODE, öznitelik düğüm tipine ilişkin değişmezdir.
3. Node.TEXT_NODE, metin düğüm tipine ilişkin değişmezdir.
4. Node.DOCUMENT_NODE, belge düğüm tipine ilişkin değişmezdir.

Başka birkaç düğüm tipi daha vardır, ancak HTML işlemlerinde, bu dördünün dışındakiler
çok seyrek olarak kullanılır. Bu değişmezlerin her birine ilişkin değerlerin DOM belirtiminde
tanımlanmasına rağmen ben, bilerek bunları atladım; değerle hiçbir zaman doğrudan
çalışmamalısınız, değişmezlerin amacı budur!

nodeType özelliği

Bir düğümü yukarıdaki değişmezlerle karşılaştırmak için nodeType özelliğini


dekullanabilirsiniz -- bu özellik DOM düğüm tipinde tanımlanır ve tüm düğümler tarafından
kullanılabilir:

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 84/129


var someNode = document.documentElement.firstChild;
if (someNode.nodeType == Node.ELEMENT_NODE) {
alert("We've found an element node named " + someNode.nodeName);
} else if (someNode.nodeType == Node.TEXT_NODE) {
alert("It's a text node; the text is " + someNode.nodeValue);
} else if (someNode.nodeType == Node.ATTRIBUTE_NODE) {
alert("It's an attribute named " + someNode.nodeName
+ " with a value of '" + someNode.nodeValue + "'");
}

Bu oldukça basit bir örnektir, ancak asıl nokta da budur: bir düğüm tipinin alınması basittir.
Daha zor olan konu, düğümün tipini öğrendikten sonra düğümle ne yapacağınızı bilmektir;
ancak düğüm, metin, öznitelik ve öğe tipleri konusunda sağlam bir bilgiyle, DOM
programlamasını kendi başınıza üstlenmeye hazırsınız.

Ya da neredeyse hazırsınız diyelim.

Çalışmalar için bir anahtar

nodeType özelliği, düğümlerle çalışmanız için gereken bileti size sağlayacakmış gibi
görünüyor -- ne tip bir düğümle çalıştığınızı anlamanıza ve daha sonra, bu düğümle ilgili kodu
yazmanıza olanak tanıyor. Buradaki sorun, yukarıda tanımlanan Node değişmezlerinin
Internet Explorer üzerinde düzgün çalışmamasıdır. Bu nedenle, Node.ELEMENT_NODE,
Node.TEXT_NODE ya da diğer değişmezleri kodunuzda kullanırsanız, Internet Explorer Şekil
4'te gördüğünüze benzer bir hata verir.

Şekil 4. Internet Explorer bir hata bildirir

Internet Explorer, JavaScript'inizde Node değişmezini her kullanışınızda bu hatayı bildirir.


Dünyadaki kullanıcıların büyük çoğunluğu hala Internet Explorer kullandığı için kodunuzda
Node.ELEMENT_NODE ya da Node.TEXT_NODE gibi yapıları kullanmaktan kaçınabilirsiniz.
Internet Explorer programının gelecek sürümü olan Internet Explorer 7.0'da bu sorunun

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 85/129


düzeltilmesi beklense de, Internet Explorer 6.x sürümünün yoğun olarak kullanımdan
kalkması birkaç yıl sürebilir. Dolayısıyla Node değişmezini kullanmaktan kaçının; DOM
kodunuzun (ve Ajax uygulamalarınızın) tüm ana tarayıcılarda çalışması önemlidir.

Sonuç

En üste ulaşmaya hazır mısınız?

DOM'yi gerçekten anlamaya çalışır ve


sonunda bu konuda uzmanlaşırsanız, en üst
Web programlama beceri düzeyine
erişirsiniz. Web programcılarının çoğu
kayan resimler yazmak ya da bir formdan
değerleri almak için JavaScript'i nasıl
kullanacağını bilir; hatta bazıları, sunucuya
istek göndermeyi ve sunucudan nasıl yanıt
alınacağını da bilir (bu dizinin ilk birkaç
makalesinden sonra sizin de bunu yapıyor
olmanız gerekir). Ancak, bir Web
sayfasının yapısını hızla değiştirmek
cesaretsiz ya da deneyimsiz programcılara
göre değildir.

Bu dizinin son birkaç makalesinde birçok şey öğrendiniz. Bu noktada, oturup bir sonraki
makalede DOM ağacının tüm akıllı kullanım çeşitlerini ele almamı beklememelisiniz. Şimdiki
ev ödeviniz DOM ile hoş etkileri ya da parlak arabirimleri nasıl yaratacağınızı keşfetmek. Bu
son iki makalede öğrendiklerinizi gözden geçirin ve deney yapıp kodlarla biraz oynamaya
başlayın. Bir masaüstü uygulamasını andıran, bir kullanıcı işlemine yanıt olarak nesnelerin
ekranda hareket ettiği bir Web sitesi oluşturup oluşturamayacağınızı görün.

Daha da iyisi, ekrandaki her nesnenin çevresine bir sınır çizin ve nesnelerin DOM ağacındaki
yerlerini görün ve nesneleri hareket ettirmeye başlayın. Düğümler oluşturun ve bunları var
olan alt öğe listelerine ekleyin; iç içe geçmiş birçok düğümden oluşan düğümleri kaldırın; bir
düğümün CSS stilini değiştirin ve bu değişikliklerin alt düğümler tarafından alınıp
alınmadıklarına bakın. Olasılıklar sınırsızdır ve yeni bir şeyi her deneyişinizde yeni bir şey
öğrenirsiniz. Web sayfalarınızla oynamanın tadını çıkarın.

Daha sonra, DOM'ye özel bu üçlemenin son parçasında DOM'nin bazı havalı ve ilginç
uygulamalarını programlamanızla nasıl birleştireceğinizi göstereceğim. Kavramsal olarak
konuşmayı ve API'yi anlatmayı bırakıp size biraz kod göstereceğim. O zamana kadar,
kendinize ait birkaç parlak fikir bulun ve kendi başınıza nelergerçekleştirebileceğinizi görün.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 86/129


Kaynaklar

Bilgi Edinme

• Ajax'a giriş konusunda yayınlanan developerWorks serisinin önceki makalelerine


bakın:
o "Introduction to Ajax: Understanding Ajax, a productive approach to building
Web sites, and how it works:" (Ajax'a Giriş: Web siteleri oluşturmak için
kullanılan verimli bir yaklaşım olarak Ajax'ı ve nasıl çalıştığını anlama )
başlıklı Bölüm 1'de, Ajax bileşen teknolojilerinin birlikte nasıl çalıştığı
gösterilmekte ve XMLHttpRequest nesnesinin de içinde bulunduğu Ajax'ın
merkezi kavramları ortaya çıkarılmaktadır (Aralık 2005).
o "Make asynchronous requests with JavaScript and Ajax: Use
XMLHttpRequest for Web requests:" (JavaScript ve Ajax ile zamanuyumsuz
istekler oluşturma: Web istekleri için XMLHttpRequest kullanma) başlıklı
Bölüm 2'de, tarayıcılar arasında XMLHttpRequest örneklerinin nasıl
yaratılacağı, isteklerin oluşturulması ve gönderilmesi ve sunucuya yanıt
verilmesi gösterilmektedir (Ocak 2006).
o "Advanced requests and responses in Ajax:" (Ajax'ta gelişmiş istekler ve
yanıtlar) başlıklı Bölüm 3'te, standart Web formlarının Ajax ile çalışması ve
HTTP durum kodlarıyla, hazır olma durumlarıyla ve XMLHttpRequest
nesnesiyle ilgili bilgilerinizi nasıl artırabileceğiniz gösterilmektedir (Şubat
2006).
o "Exploiting DOM for Web response" (Web yanıtı için DOM'yi kullanma)
başlıklı Bölüm 4'te DOM tanıtılır ve HTML'nin bir nesne modeline
dönüştürülmesinin Web sayfalarını nasıl yanıt verebilir ve etkileşimli kıldığı
anlatılır (Mart 2006).

• Use Ajax with WebSphere Portal (Ajax'ı WebSphere Portal ile kullanma), portal
performansını artırmak, daha temiz bir portal uygulaması mimarisi ve -- en önemlisi --
kullanıcılarınıza çok daha hızlı yanıt veren bir portal yaratmak için. (developerWorks,
Haziran 2006)

• Ajax for Java developers: Build dynamic Java applications, Philip McCarthy: Java
bakış açısını kullanarak sunucu tarafından Ajax'a bakın ve dinamik Web uygulaması
deneyimleri oluşturmak için çığır açan bir yaklaşımla tanışın (developerWorks, Eylül
2005).

• Ajax for Java developers: Java object serialization for Ajax, Philip McCarthy: Java
nesnesi diziselleştirmesine ilişkin beş yaklaşımı inceleyin ve ağ üzerinden nesneleri
nasıl göndereceğinizi ve Ajax ile nasıl etkileşime geçeceğinizi öğrenin
(developerWorks, Ekim 2005).

• Call SOAP Web services with Ajax, Part 1: Build the Web services client, James
Snell: Ajax'ın var olan SOAP tabanlı Web hizmetleriyle bütünleştirilmesine ilişkin bu
ileri düzey makaleyi inceleyin; Ajax tasarım şablonunu kullanarak Web tarayıcısı
tabanlı SOAP Web hizmetleri istemcisini nasıl uygulayacağınızı gösterir
(developerWorks, Ekim 2005).

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 87/129


• Ajax: A New Approach to Web Applications: Ajax moniker teriminin ilk kez
kullanıldığı bu makaleyi okuyun -- tüm Ajax geliştiricileri bu makaleyi okumalıdır.

• World Wide Web Consortium'daki DOM Ana Sayfası: DOM ile ilgili her şeyin
başlangıç noktası olan bu siteyi ziyaret edin.

• DOM Level 3 Core Specification (DOM Düzey 3 Çekirdek Belirtimi): Çeşitli


dillerden Belge Nesne Modeli'nin kullanabileceği tipleri ve özellikleri kullanarak
çekirdek DOM'yi tanımlayın.

• ECMAScript language bindings for DOM (DOM için ECMAScript dil


ilişkilendirmeleri): Bir JavaScript programcısıysanız ve kodunuz için DOM kullanmak
istiyorsanız, Düzey 3 Belge Nesne Modeli Çekirdeği tanımlarına ilişkin bu ek ilginizi
çekecektir.

• developerWorks Web mimarisi alanı: Web oluşturma becerilerinizi makaleler,


senaryolar, forumlar, vb. araçlarla genişletin.

• developerWorks teknik etkinlikleri ve Web yayınları: Teknik geliştiricilere yönelik bu


yazılım brifinglerini takip edin.

Ürün ve teknoloji edinme

• Head Rush Ajax, Brett McLaughlin (O'Reilly Media, Inc., Mart 2006): Bu makaledeki
fikirleri Head First yöntemiyle öğrenin.

• Java and XML, İkinci Basım, Brett McLaughlin (Ağustos 2001, O'Reilly Media, Inc.):
Yazarın, XHTML ve XML dönüşümleriyle ilgili düşüncelerini okuyun.

• JavaScript: The Definitive Guide, David Flanagan (Kasım 2001, O'Reilly Media,
Inc.): JavaScript ve dinamik Web sayfalarıyla çalışmaya ilişkin kapsamlı yönergeleri
inceleyin. Yayınlanacak olan yeni basımda Ajax ile ilgili iki yeni bölüm vardır.

• Head First HTML with CSS & XHTML, Elizabeth ve Eric Freeman (Aralık 2005,
O'Reilly Media, Inc.): Standartlaşmış HTML ve XHTML ve CSS'yi HTML'ye
uygulamayla ilgili daha fazla bilgi öğrenin.

• IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki


geliştirme projenizi oluşturun.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 88/129


Ajax'ta Uzmanlaşma, Bölüm 6:
DOM tabanlı Web uygulamaları oluşturma
Yeniden yüklemeye gerek kalmadan bir Web sayfasının kullanıcı arabirimini değiştirmek için,
mükemmel Ajax yardımcıları olan DOM ve JavaScript'i birlikte kullanın.

Düzey: Orta

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

12 Eylül 2006

Etkileşimli Ajax uygulamaları oluşturmak için Belge Nesne Modeli (DOM) ile JavaScript'i
birleştirin. Bu dizinin önceki makalelerinde DOM programlamasıyla ilgili kavramları
incelediniz (Web tarayıcısının bir Web sayfasını ağaç olarak nasıl görüntülediği gibi) ve şimdi
DOM içinde kullanılan programlama yapılarını anlıyor olmalısınız. Bu makalede, tüm bu
bilgileri uygulamaya geçirecek ve bazı hoş etkilere sahip basit bir Web sayfası
oluşturacaksınız. Oluşturulan tüm öğeler DOM'yi kullanmak üzere JavaScript ile, sayfanın
yeniden yüklenmesini ya da yenilenmesini gerektirmeden oluşturulacak.

Belge Nesne Modeli ya da DOM'nin tanıtımıyla ilgili iki tam makale okudunuz; şimdiye
kadar DOM'nin nasıl çalıştığını anlamışsınızdır. (İlk iki DOM makalesine ve Ajax dizisindeki
önceki makalelere ilişkin bağlantıları görmek için Kaynaklar bölümüne bakın.) Bu makalede,
anladıklarınızı uygulamaya geçireceğiz. Kullanıcı işlemlerine göre değişen bir kullanıcı
arabirimine sahip, temel bir Web uygulaması geliştireceksiniz -- elbette, bu arabirimi
değiştirme işlemi için DOM'yi kullanacaksınız. Bu makaleyi bitirdiğinizde, DOM ile ilgili
öğrendiğiniz tekniklerin ve kavramların çoğunu uygulamaya koyacaksınız.

Son iki makaleyi okuduğunuzu varsayıyorum; eğer okumadıysanız, DOM'yi ve Web


tarayıcılarının sağladığınız HTML ve CSS'yi Web sayfasını gösteren tek bir ağaç yapısına
nasıl dönüştürdüğünü iyice anlamak için bu makaleleri gözden geçirin. Şimdiye kadar sözünü
ettiğim tüm DOM ilkeleri bu makalede, DOM tabanlı dinamik bir Web sayfası ,(her ne kadar
basit bir örnek olsa da)oluşturmak için kullanılacaktır. Bu makalenin herhangi bir yerinde
takılırsanız, durup önceki iki makaleyi gözden geçirebilir ve takıldığınız yere geri
dönebilirsiniz.

Örnek uygulamayla başlama

Kod üzerine bir not

Dikkatinizi özel olarak DOM ve


JavaScript kodunda tutmak için biraz
özensiz davrandım ve HTML'yi
yerleşik stil ile yazdım (örneğin, h1 ve

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 89/129


p öğelerindeki align özniteliği gibi).
Deneme amacıyla bu kabul edilebilir
olsa da, zamanınızı ayırıp
geliştirdiğiniz üretim uygulamaları
için tüm stillerinizi dış CSS stil
sayfalarına almanızı öneririm.

Çok temel bir uygulama oluşturup daha sonra biraz da DOM büyüsü ekleyerek iş başlayalım.
DOM'nin Web sayfasındaki öğeleri bir form sunmadan hareket ettirebildiği düşüncesini -- bu
nedenle de mükemmel bir Ajax yardımcısı olduğunu -- aklınızdan çıkarmadan, yalnızca bir
silindir şapka ve Hocus Pocus! etiketli bir düğmenin bulunduğu basit bir sayfa oluşturalım.
(Bunun nereye gideceğini tahmin edebiliyor musunuz?)

İlk HTML

Liste 1'de bu sayfaya ilişkin HTML gösterilmektedir; bu yalnızca basit bir resim ve
basabileceğiniz bir düğme ile birlikte başlık ve formdan oluşan bir gövdedir.

Liste 1. Örnek uygulamaya ilişkin HTML


<html>
<head>
<title>Magic Hat</title>
</head>

<body>

<h1 align="center">Welcome to the DOM Magic Shop!</h1>


<form name="magic-hat">
<p align="center">
<img src="topHat.gif" />
<br /><br />

<input type="button" value="Hocus Pocus!" />


</p>
</form>
</body>
</html>

Bu HTML'yi ve bu makalede kullanılan tüm resimleri, bu makalenin sonundaki Yüklemeler


bölümünde bulabilirsiniz. Ancak, size yalnızca resimleri yüklemenizi ve daha sonra, ben
makalede uygulamayı oluştururken, sizin de örnek üzerinden elinizle HTML'yi yazmanızı
öneririm. Bu yöntemle DOM kodunu, yalnızca makaleyi okuyup tamamlanmış uygulamayı
açmaktan çok daha iyi anlarsınız.

Örnek Web sayfasının görüntülenmesi

Burada herhangi bir zorluk yok; sayfayı açtığınızda Şekil 1'dekine benzer bir görüntü
görmeniz gerekir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 90/129


Şekil 1. Biraz sıkıcı görünen bir silindir şapka

HTML ile ilgili son bir nokta

Burada dikkat etmeniz gereken önemli bir nokta, Liste 1 ve Şekil 1'deki düğmenin button
tipinde olduğu, bir gönderme düğmesi olmadığıdır. Bir gönderme düğmesi kullanırsanız,
düğmeye basıldığında tarayıcı formu göndermeyi dener; elbette, formda action özniteliği
olmadığından (özellikle eklenmemiştir), etkinlik olmayan sonsuz bir döngü başlatır. (Neler
olup biteceğini görmek için bunu kendi başınıza denemelisiniz.) Normal bir giriş düğmesi
kullanarak -- ve gönderme düğmesi kullanmayarak -- düğmeye bir JavaScript işlevi
bağlayabilir ve tarayıcıyla formu göndermeden etkileşime geçebilirsiniz.

Örnek uygulamaya yeni özelliklerin eklenmesi

Şimdi, Web sayfasını biraz JavaScript, DOM ve biraz da resim büyüsüyle güzelleştirelim.

getElementById() işlevinin kullanılması

Açıkçası, tavşan yoksa sihirli bir şapkanın pek bir değeri de olmaz. Bu yüzden, var olan
sayfadaki resmi (yeniden Şekil 1'e bakın) Şekil 2'de gösterilen gibi bir tavşan resmiyle
değiştirerek işe başlayın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 91/129


Şekil 2. Aynı şapka, ancak bu kez bir tavşanla

Biraz DOM ustalığı kullanmak için ilk olarak Web sayfasında img öğesini gösteren DOM
düğümünü arayın. Genel olarak bunu yapmanın en kolay yolu, Web sayfasını belirten
document nesnesindeki getElementById() yönteminin kullanılmasıdır. Bu yöntemi daha
önce görmüştünüz; bu yöntem aşağıdaki gibi çalışır:

var elementNode = document.getElementById("id-of-element");

HTML'ye id özniteliğinin eklenmesi

Bu oldukça temel bir JavaScript kodudur, ancak HTML'nizde biraz çalışma gerektirir:
Erişmek istediğiniz öğeye bir id özniteliği eklemelisiniz. Örnekte değiştirmek istediğiniz img
öğesi olduğu için (tavşanın bulunduğu yeni resim ile değiştirilecek), HTML'nizi Liste 2'de
gösterilen şekilde değiştirmeniz gerekir.

Liste 2. Bir id özniteliğinin eklenmesi


<html>
<head>
<title>Magic Hat</title>
</head>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 92/129


<body>

<h1 align="center">Welcome to the DOM Magic Shop!</h1>


<form name="magic-hat">
<p align="center">
<img src="topHat.gif" id="topHat" />

<br /><br />


<input type="button" value="Hocus Pocus!" />
</p>
</form>
</body>
</html>

Sayfayı yeniden yüklerseniz (ya da yeniden açarsanız) farklı hiçbir şey görmezsiniz; id
özniteliğinin eklenmesi Web sayfasında görsel hiçbir değişikliğe neden olmaz. Ancak,
JavaScript ve DOM'yi kullanarak bir öğe üzerinde daha kolay çalışmaya olanak tanır.

img öğesinin kavranması

Artık getElementById() yöntemini kolayca kullanabilirsiniz. İstediğiniz öğenin tanıtıcısına


sahipsiniz -- topHat -- ve bunu, yeni bir JavaScript değişkeninde saklayabilirsiniz. HTML
sayfanıza Liste 3'te gösterilen kodu ekleyin.

Liste 3. img öğesine erişim


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
}
</script>

</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">
<p align="center">

<img src="topHat.gif" id="topHat" />


<br /><br />
<input type="button" value="Hocus Pocus!" />
</p>
</form>
</body>

</html>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 93/129


Yine bu noktada, Web sayfasının yüklenmesi ya da yeniden yüklenmesi heyecan verici bir
şeyler görmenize neden olmaz. Artık resme erişiminiz olmasına rağmen, onunla ilgili henüz
herhangi bir şey yapmadınız.

Resmin değiştirilmesi, zor yol

İstediğiniz değişikliği iki yolla yapabilirsiniz: Zor yol ve kolay yol. Tüm iyi programcılar gibi
ben de kolay yolu tercih ederim; ancak, uzun yoldan yürümek sizin için harika bir DOM
alıştırması olacaktır ve kesinlikle zaman harcadığınıza değecektir. Önce zor yoldan resmi
nasıl değiştirebileceğimize bakalım; daha sonra, aynı değişikliği kolay yoldan nasıl
yapabileceğinizi göreceksiniz.

Var olan resmi, tavşanın bulunduğu yeni resimle değiştirmek için yapmanız gerekenler
şunlardır:

1. Yeni bir img öğesi oluşturun.


2. Var olan img öğesinin ana öğesi (kapsayıcısı) olan öğeye erişin.
3. Yeni img öğesini, kapsayıcının bir alt öğesi olarak, var olan img öğesinin hemen
önüne yerleştirin.
4. Eski img öğesini kaldırın.
5. Kullanıcı Hocus Pocus! düğmesini tıklattığında, oluşturduğunuz JavaScript işlevinin
çağrılması için gerekli ayarlamaları yapın.

Yeni bir img öğesi oluşturulması

Son iki makalemden de hatırlayacağınız gibi, DOM ile ilgili hemen hemen her şeyin
anahtarıdocument nesnesidir. Bu nesne, tüm bir Web sayfasını temsil eder,
getElementById() gibi güçlü yöntemlere erişmenizi sağlar ve yeni düğümler oluşturmanıza
olanak tanır. Şimdi kullanmak isteyeceğiniz de bu son özelliktir.

Tam olarak söylersek, yeni bir img öğesi yaratmanız gerekir. DOM içinde her şeyin bir
düğüm olduğunu, ancak düğümlerin de üç temel gruba ayrıldığını unutmayın:

• Öğeler
• Öznitelikler
• Metin düğümleri

Başka gruplar da vardır, ama bu üçü programlama gereksinimlerinizin %99'unu karşılar. Bu


örnekte, img tipinde yeni bir öğeye ihtiyacınız vardır. Dolayısıyla JavaScript'inizde bu kodun
bulunması gerekir:

var newImage = document.createElement("img");

Bu, element tipinde, img öğe adıyla yeni bir düğüm oluşturur. HTML'de bu temel olarak
şöyledir:

<img />

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 94/129


DOM'nin, iyi hazırlanmış bir HTML oluşturacağını hatırlayın; diğer bir deyişle, öğe, hem
başlangıç hem de bitiş biçim imi içerir ve şu an için boştur. Yapılması gereken şey bu öğeye
içerik ya da öznitelik eklemek ve daha sonra, bu öğeyi Web sayfasına yerleştirmektir.

İçerik açısından img öğesi, boş bir öğedir. Ancak, bir öznitelik eklemeniz gerekir: Yüklenecek
resmi belirten src özniteliği. Burada addAttribute() gibi bir yöntem kullanmanız
gerektiğini düşünebilirsiniz, ancak bu doğru değil. DOM belirtimini oluşturanlar,
programcılar olarak bizlerinkısayollardan hoşlanacağımızı düşündüler (ki gerçekten
kısayolları severiz!) ve yeni öznitelikleri eklemek ve var olanların değerini değiştirmek için
tek bir yöntem oluşturdular: setAttribute().

setAttribute() yöntemini çağırır ve var olan bir öznitelik sağlarsanız, değeri sağladığınız
değerle değiştirilir. Ancak, setAttribute() yöntemini çağırır ve var olmayan bir öznitelik
sağlarsanız, DOM sağladığınız değeri kullanarak sessizce bu özniteliği ekler. Bir yöntem, iki
amaç! JavaScript'inize şunları eklemeniz gerekir:

var newImage = document.createElement("img");


newImage.setAttribute("src", "rabbit-hat.gif");

Bu, resmi oluşturur ve kaynağını uygun şekilde ayarlar. Bu noktada, HTML'niz Liste 4'teki
gibi görünür.

Liste 4. DOM ile yeni bir resmin oluşturulması

<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
var newImage = document.createElement("img");
newImage.setAttribute("src", "rabbit-hat.gif");
}
</script>

</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">
<p align="center">

<img src="topHat.gif" id="topHat" />


<br /><br />
<input type="button" value="Hocus Pocus!" />
</p>
</form>
</body>

</html>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 95/129


Bu sayfayı yükleyebilirsiniz, ancak hiçbir hareket beklemeyin; aslında henüz gerçek Web
sayfasını etkileyecek hiçbir şey yapmadınız. Ayrıca, yapılacaklar listesindeki adım 5'e
bakarsanız, henüz JavaScript işlevinin bile çağırılmadığını fark edeceksiniz!

Özgün resmin üst öğesinin alınması

Artık yerleştirilmeye hazır bir resminiz olduğuna göre, bunun yerleştirileceği yere ihtiyacınız
var. Ancak, bunu var olan resme yerleştirmeyeceksiniz; bunun yerine, yeni resmi var olan
resmin önüne koymak ve daha sonra var olan resmi kaldırmak isteyebilirsiniz. Bunu yapmak
için, tüm bu yerleştirme ve kaldırma işlemlerinde gerçekten anahtar role sahip, var olan
resmin üst öğesi gereklidir.

Önceki makalelerden de hatırlayacağınız gibi DOM, bir Web sayfasını gerçekten de bir ağaç
gibi, düğüm hiyerarşisi içinde görür. Her düğümün bir üst öğesi (düğümün alt öğe olduğu
ağaçtaki bir üst düğüm) ve büyük olasılıkla kendi alt öğeleri vardır. Bu resim örneğindealt öğe
yoktur -- resimlerin boş öğeler olduklarını hatırlayın -- ancak kesinlikle bir üst öğe vardır. Üst
öğenin ne olduğu hiç önemli değil; yalnızca bu öğeye erişmeniz gerekir.

Bunu yapmak için her DOM düğümünde olan parentNode özelliğini kullanabilirsiniz:

var imgParent = hatImage.parentNode;

Bu kadar basit! Üst öğenin alt öğeleri olabileceğini biliyorsunuz, çünkü zaten bir alt öğesi var:
Eski resim. Bunun ötesinde, üst öğenin bir div, p ya da sayfanın body öğesi mi olduğunu
bilmeniz gerekmez; bu önemli değildir!

Yeni resmin yerleştirilmesi

Eski resmin üst öğesine eriştiğinize göre, yeni resmi ekleyebilirsiniz. Bu oldukça kolay bir
işlemdir; bir alt öğe eklemek için birkaç yöntem kullanabilirsiniz:

• insertBefore(newNode, oldNode)
• appendChild(newNode)

Yeni resmin tam olarak eski resimle aynı yerde görünmesini istediğiniz için insertBefore()
yöntemini (ve removeChild() yöntemini) kullanmanız gerekir. Yeni resim öğesini var olan
resmin hemen önüne yerleştirmek için kullanacağınız JavaScript satırı şöyledir:

var imgParent = hatImage.parentNode;


imgParent.insertBefore(newImage, hatImage);

Bu noktada, eski resmin üst öğesinin iki alt resmi vardır: Yeni resim ve hemen ardından gelen
eski resim. Bu resimlerin çevresindeki içeriğin değişmediğini ve bu içeriğin sırasının, tam
olarak ekleme işleminden önceki sırada kaldığını belirtmek gerekir. Yalnızca üst öğenin artık
eski resmin önünde bir ek alt öğesi (yeni resim) daha vardır.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 96/129


Eski resmin kaldırılması

Web sayfasında yalnızca yeni resmi istediğiniz için şimdi yapmanız gereken eski resmi
kaldırmaktır. Eski resim öğesinin üst öğesine erişiminiz olduğu için bu kolay olacaktır.
removeChild() yöntemini çağırıp bunu kaldırmak istediğiniz düğüme geçirebilirsiniz:

var imgParent = hatImage.parentNode;


imgParent.insertBefore(newImage, hatImage);
imgParent.removeChild(hatImage);

Bu noktada, eski resmi yenisiyle değiştirdiniz. HTML'niz Liste 5'teki gibi görünmelidir.

Liste 5. Eski resmin yenisiyle değiştirilmesi


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
var newImage = document.createElement("img");
newImage.setAttribute("src", "rabbit-hat.gif");
var imgParent = hatImage.parentNode;
imgParent.insertBefore(newImage, hatImage);
imgParent.removeChild(hatImage);
}
</script>

</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">
<p align="center">

<img src="topHat.gif" id="topHat" />


<br /><br />
<input type="button" value="Hocus Pocus!" />
</p>
</form>
</body>

</html>

JavaScript'in bağlanması

Son -- ve belki de en kolay -- adım olarak, HTML formunuzu, az önce yazdığınız JavaScript
işlevine bağlarsınız. showRabbit() işlevinin, kullanıcının Hocus Pocus! düğmesini her
tıklatmasında çalışmasını istiyorsunuz. Bunu gerçekleştirmek için HTML'nize basit bir
onClick olay işleyicisi ekleyin:

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 97/129


<input type="button" value="Hocus Pocus!" onClick="showRabbit();" />

Bu işlem, JavaScript programlamanızın bu noktasında oldukça rutin olmalı. Bunu HTML


sayfanıza ekleyin, sayfayı kaydedin ve daha sonra, sayfayı Web tarayıcınızda yükleyin. Sayfa
başlangıçta Şekil 1'deki gibi görünür; Hocus Pocus! düğmesini tıklatın ve sonuçta, Şekil
3'teki gibi görünmesi gerekir.

Şekil 3. Tavşan ortaya çıkar

Resmin değiştirilmesi, biraz daha kolay yol

Resmi değiştirmek için uyguladığınız adımlara dönüp bakar ve daha sonra, düğümler üzerinde
gerçekleştirebileceğiniz çeşitli yöntemleri gözden geçirirseniz, replaceNode() adlı bir

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 98/129


yöntemi fark edebilirsiniz. Bu yöntem, bir düğümü diğeriyle değiştirebilmenizi sağlar.
Gerçekleştirdiğiniz adımları yeniden düşünün:

1. Yeni bir img öğesi oluşturun.


2. Var olan img öğesinin ana öğesi (kapsayıcısı) olan öğeye erişin.
3. Yeni img öğesini, kapsayıcının bir alt öğesi olarak, var olan img öğesinin hemen
önüne yerleştirin.
4. Eski img öğesini kaldırın.
5. Kullanıcı Hocus Pocus! düğmesini tıklattığında, oluşturduğunuz JavaScript işlevinin
çağrılması için gerekli ayarlamaları yapın.

replaceNode() yöntemiyle, gerçekleştirmeniz gereken adımların sayısını azaltabilirsiniz.


Adım 3 ve 4 birleştirdiğinizde süreç aşağıdaki gibi olur:

1. Yeni bir img öğesi oluşturun.


2. Var olan img öğesinin ana öğesi (kapsayıcısı) olan öğeye erişin.
3. Eski img öğesini, az önce oluşturduğunuz yeni öğeyle değiştirin.
4. Kullanıcı Hocus Pocus! düğmesini tıklattığında, oluşturduğunuz JavaScript işlevinin
çağrılması için gerekli ayarlamaları yapın.

Bu çok büyük bir şey gibi görünmeyebilir, ancak kesinlikle kodunuzu basitleştirir. Liste 6'da,
insertBefore() yöntemini kaldırarak ve removeChild() yöntemini çağırarak bu değişikliği
nasıl yapacağınız gösterilmektedir.

Liste 6. Eski resmin yenisiyle değiştirilmesi (bir adımda)


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
var newImage = document.createElement("img");
newImage.setAttribute("src", "rabbit-hat.gif");
var imgParent = hatImage.parentNode;
imgParent.replaceChild(newImage, hatImage);

}
</script>
</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">

<p align="center">
<img src="topHat.gif" id="topHat" />
<br /><br />
<input type="button" value="Hocus Pocus!" onClick="showRabbit();" />
</p>
</form>
</body>

</html>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 99/129


Bu da büyük bir değişiklik değildir, ancak DOM kodlamasındaki oldukça önemli bir noktayı
gösterir: Belirli bir görevi gerçekleştirmek için genellikle birden çok yol bulabilirsiniz. Çoğu
kez dört ya da beş adımda gerçekleştirebileceğiniz bir işlemi, kullanabileceğiniz DOM
yöntemlerini dikkatli bir şekilde gözden geçirir ve bir görevi gerçekleştirebileceğiniz daha
kısa yolları görebilirseniz, iki ya da üç adıma indirebilirsiniz.

Resmin değiştirilmesi, (gerçekten) kolay yol

Az önce de belirttiğim gibi bir görevi gerçekleştirmek için hemen her zaman daha kolay bir
yol olduğu için, şimdi şapka resmini tavşan resmiyle değiştirmenin çok daha kolay yolunu
göstereceğim. Bu makale üzerinde çalışırken bu yaklaşımın ne olduğunu anlayabildiniz mi?
Size bir ipucu vereyim: Özniteliklerle ilgili bir şey.

Resim öğesinin büyük oranda, bir yerlerdeki (bir yerel URI ya da bir dış URL) bir dosyaya
başvuruda bulunan src özniteliği tarafından denetlendiğini hatırlayın. Şimdiye kadar, resim
düğümünü yeni bir resimle değiştirdiniz; ancak yalnızca var olan resmin src özniteliğini
değiştirmek çok daha kolaydır! Bu, yeni düğüm oluşturma, üst öğeyi bulma ve eski düğümü
değiştirme ile ilgili tüm adımları tek bir adıma indirir:

hatImage.setAttribute("src", "rabbit-hat.gif");

Hepsi bu! Bu çözümü tüm Web sayfası bağlamında gösteren Liste 7'ye bakın.

Liste 7. src özniteliğinin değiştirilmesi


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "rabbit-hat.gif");

}
</script>
</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">

<p align="center">
<img src="topHat.gif" id="topHat" />
<br /><br />
<input type="button" value="Hocus Pocus!" onClick="showRabbit();" />
</p>
</form>
</body>

</html>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 100/129


DOM ile ilgili harika şeylerden biri budur: Bir özniteliği değiştirdiğinizde, Web sayfası
hemen değişir. Resim yeni bir dosyayı gösterir göstermez, tarayıcı dosyayı yükler ve sayfa
güncellenir. Yeniden yüklemeye gerek yoktur ve yeni bir resim öğesi yaratmanız bile
gerekmez! Sonuç yukarıda gösterilen Şekil 3 ile aynıdır -- tek fark kodun çok daha kolay
olmasıdır.

Tavşanın gizlenmesi

Şu anda Web sayfası oldukça etkileyici, ancak hala biraz ilkel durumda. Tavşan şapkadan
çıkıyor, ancak ekranın altındaki düğmede tavşan çıktıktan sonra da Hocus Pocus! yazmaya ve
düğme, showRabbit() işlevini çağırmaya devam ediyor. Bu, tavşan çıktıktan sonra düğmeyi
tıklatırsanız, boşuna zaman harcayacağınız anlamına gelir. Daha da önemlisi, bu hiçbir işe
yaramaz ve yararsız düğmeler hiçbir zaman iyi bir şey değildir. Birkaç değişiklik daha
yapmak ve tavşan ister şapkanın içinde ister dışında olsun düğmenin yararlı olmasını
sağlamak için DOM'yi kullanıp kullanamayacağınızı görelim.

Düğme etiketinin değiştirilmesi

Yapılabilecek en kolay şey, kullanıcı düğmeyi tıkladıktan sonra düğmenin etiketinin


değişmesidir. Böylece, sihirli başka bir şeyler daha olacağını belirtmez; bir Web sayfası için
en kötü şey kullanıcıya doğru olmayan bir şeyin ima edilmesidir. Düğmenin etiketini
değiştirmeden önce düğüme erişmeniz ve bunu yapabilmek için önce, düğmeye başvuruda
bulunmak için kullanacağınız bir tanıtıcıya (id) sahip olmanız gerekir. Bununeski şapka
olması gerekiyordu, değil mi? Liste 8'de düğmeye bir id özniteliği eklenmektedir.

Liste 8. Bir id özniteliğinin eklenmesi


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "rabbit-hat.gif");
}
</script>

</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">
<p align="center">

<img src="topHat.gif" id="topHat" />


<br /><br />
<input type="button" value="Hocus Pocus!" id="hocusPocus"
onClick="showRabbit();" />
</p>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 101/129


</form>
</body>

</html>

Artık JavaScript'te düğmenize erişmeniz basittir:

function showRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "rabbit-hat.gif");
var button = document.getElementById("hocusPocus");
}

Elbette, düğme etiketinin değerini değiştirmek için bir sonraki JavaScript'in satırını çoktan
yazmış olabilirsiniz. Burada yine setAttribute() yöntemi gündeme gelir:

function showRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "rabbit-hat.gif");
var button = document.getElementById("hocusPocus");
button.setAttribute("value", "Get back in that hat!");
}

Bu basit DOM çalışmasıyla, tavşan ortaya çıkar çıkmaz düğmenin etiketi değişir. Bu noktada,
HTML'niz ve tamamlanmış showRabbit() işleviniz Liste 9'daki gibi görünmelidir.

Liste 9. (Şimdilik) Tamamlanmış Web sayfası


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "rabbit-hat.gif");
button.setAttribute("value", "Get back in that hat!");
}
</script>

</head>

<body>
<h1 align="center">Welcome to the DOM Magic Shop!</h1>
<form name="magic-hat">
<p align="center">

<img src="topHat.gif" id="topHat" />


<br /><br />
<input type="button" value="Hocus Pocus!" id="hocusPocus"
onClick="showRabbit();" />

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 102/129


</p>
</form>
</body>

</html>

Tavşanın şapkaya geri girmesi

Yeni düğme etiketinden de tahmin edeceğiniz gibi, tavşanın şapkaya geri girmesinin zamanı
geldi. Aslında bu, tavşanı çıkarmak için yaptığınız işlemleri tersine çevirmenizle aynı süreçtir:
Resmin src özniteliği yeniden eski resme değiştirilir. Bunu yapmak için yeni bir JavaScript
işlevi oluşturun:

function hideRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "topHat.gif");
var button = document.getElementById("hocusPocus");
button.setAttribute("value", "Hocus Pocus!");
}

Bu, gerçekten de showRabbit() işlevinin yaptığı her şeyi tersine çevirmektir. Resmi eski,
tavşansız şapkaya ayarlayın, düğmeyi alın ve etiketini yeniden Hocus Pocus! olarak
değiştirin.

Olay işleyicilerle çalışma

Örnek uygulamanın bu noktada önemli bir sorunu vardır: Düğmenin etiketi değişir, ancak
düğmeyi tıkladığınızda gerçekleşen işlem değişmez. Neyse ki, DOM'yi kullanarak kullanıcı
düğmeyi tıklattığında gerçekleşen işlemi değiştirebilirsiniz. Dolayısıyla, düğmede Get back
in that hat! yazıyorsa, kullanıcı düğmeyi tıkladığında hideRabbit() işlevinin çalışmasını
istiyorsunuz demektir. Bunun tersine, tavşan gizlendiğinde, düğme showRabbit() işlevini
çalıştırır.

addEventHandler() yöntemini
kullanmakta kaçının

onclick özelliğine ek olarak,


onClick ya da onBlur gibi bir olay
işleyicisi eklemek için
kullanılabilecek bir yöntem vardır; bu
yönteme çok da şaşırtıcı olmayan bir
şekilde addEventHandler() denir. Ne
yazık ki, Microsoft™ Internet
Explorer™ bu yöntemi desteklemez;
bu nedenle, JavaScript'inizde bu
yöntemi kullanırsanız, milyonlarca

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 103/129


Internet Explorer kullanıcısı
sayfanızdan yalnızca bir hata iletisi
alır (ve akıllarından şikayetleriyle
ilgili düşünceler geçebilir). Bu
yöntemi kullanmaktan kaçının;
Internet Explorer'da çalışan bu
makaledeki yaklaşımı kullanarak aynı
sonuçları alabilirsiniz.

HTML'ye bakarsanız, burada çalıştığınız olayın onClick olduğunu görürsünüz. JavaScript'te,


bir düğmenin onclick özelliğini kullanarak bu olaya başvuruda bulunabilirsiniz. (HTML'de
özelliğe genellikle, büyük C harfiyle onClick, JavaScript'te ise tamamı küçük harfle onclick
dendiğine dikkat edin.) Demek ki, bir düğmede çalışan olayı onclick özelliğine yeni bir işlev
atayarak değiştirebilirsiniz.

Ancak ufak bir nokta vardır: onclick özelliğinin bir işlev başvurusuyla beslenmesi gerekir --
işlevin dize adı değil, işlevin kendisine bir başvuru gereklidir. JavaScript'te, bir işleve
parantez kullanmadan, adıyla başvuruda bulunabilirsiniz. Bir düğme tıklatıldığında çalışan
işlevi aşağıdaki şekilde değiştirebilirsiniz:

button.onclick = myFunction;

O zaman, HTML'nizde bu değişikliği yapmak oldukça kolay olacaktır. Düğmenin çalıştırdığı


işlevlerin değiştirildiği Liste 10'a bakın.

Liste 10. Düğmenin onClick işlevinin değiştirilmesi


<html>
<head>
<title>Magic Hat</title>
<script language="JavaScript">
function showRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "rabbit-hat.gif");
var button = document.getElementById("hocusPocus");
button.setAttribute("value", "Get back in that hat!");
button.onclick = hideRabbit;

function hideRabbit() {
var hatImage = document.getElementById("topHat");
hatImage.setAttribute("src", "topHat.gif");
var button = document.getElementById("hocusPocus");
button.setAttribute("value", "Hocus Pocus!");
button.onclick = showRabbit;
}
</script>
</head>

<body>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 104/129


<h1 align="center">Welcome to the DOM Magic Shop!</h1>

<form name="magic-hat">
<p align="center">
<img src="topHat.gif" id="topHat" />
<br /><br />
<input type="button" value="Hocus Pocus!" id="hocusPocus"
onClick="showRabbit();" />

</p>
</form>
</body>
</html>

Bu tam, kullanıma hazır bir DOM uygulamasıdır. Deneyin ve kendiniz görün!

Sonuç

Bu noktada, DOM ile rahatça çalışabiliyor olmanız gerekir. Önceki makalelerde, DOM ile
çalışmaya ilişkin temel kavramları görmüş ve API'ye ayrıntılı bir şekilde bakmıştınız; şimdi
DOM tabanlı basit bir uygulamayla çalıştınız. Bu makale üzerinde durun ve kendiniz
çevrimiçi denemeler yapın.

Bu makale, bu dizinin özellikle Belge Nesne Modeli konusuna odaklanan son makalesi
olmasına rağmen, DOM ile okuyacağınız son yazı değildir. Aslında, en azından bir dereceye
kadar DOM'yi kullanmadan Ajax ve JavaScript dünyalarında fazla bir şey yapmakta
zorlanırsınız. İster karmaşık vurgulama ve hareket etkileri oluşturun, ister yalnızca metin
blokları ve resimlerle uğraşın, DOM size kullanımı gerçekten kolay bir yöntemle bir Web
sayfasına erişim sağlar.

DOM'yi nasıl kullanacağınız konusunda emin olmadığınız noktalar olduğunu düşünüyorsanız,


bu dizinin üç makalesini de gözden geçirin; dizinin bundan sonraki makalelerinde DOM, çok
fazla açıklama yapılmadan kullanılacaktır ve eminim ki ayrıntılar içinde kaybolmak ve XML
ya da JSON gibi diğer kavramlarla ilgili önemli bilgileri kaçırmak istemezsiniz. DOM'yi
rahatlıkla kullandığınızdan, kendi başınıza DOM tabanlı birkaç uygulama yazabildiğinizden
ve önümüzdeki birkaç ay boyunca anlatacağım bazı veri formatı sorunlarıyla başa çıkmaya
hazır olduğunuzdan emin olun.

Yüklemeler

Karşıdan
Açıklama Ad Boyut yükleme
yöntemi
Yalnızca örnekteki grafikler wa-ajaxintro6/ajax_6-images_download.zip 91 KBHTTP
HTML ve grafiklerin bulunduğu
wa-ajaxintro6/ajax_6-complete_examples.zip93 KBHTTP
tam örnek

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 105/129


Kaynaklar

Bilgi Edinme

• Exploiting DOM for Web response (Web yanıtı için DOM'yi kullanma) ve Advanced
requests and responses in Ajax (Ajax'ta gelişmiş istekler ve yanıtlar): DOM
programlamasıyla ilgili bu dizinin birinci ve ikinci makalelerini okuyun ya da
Mastering Ajax (Ajax'ta Uzmanlaşma) dizisinin tamamına bakın.

• "Build dynamic Java applications" (Philip McCarthy, developerWorks, Eylül 2005):


Java™ bakış açısıyla Ajax'a sunucu tarafından bir bakış.

• "Java object serialization for Ajax" (Philip McCarthy, developerWorks, Ekim 2005):
Ağ üzerinden nesne gönderme ve Ajax ile etkileşimde bulunma konularını Java bakış
açısıyla inceler.

• "Call SOAP Web services with Ajax" (James Snell, developerWorks, Ekim 2005):
Ajax'ın var olan SOAP tabanlı Web hizmetleriyle bütünleştirilmesine ilişkin bu ileri
düzey makaleyi inceleyin; Ajax tasarım şablonunu kullanarak Web tarayıcısı tabanlı
SOAP hizmetleri istemcisini nasıl uygulayacağınızı gösterir.

• World Wide Web Consortium'daki DOM Ana Sayfası: DOM ile ilgili her şeyin
başlangıç noktasını ziyaret edin.

• DOM Level 3 Core Specification (DOM Düzey 3 Çekirdek Belirtimi): Çeşitli


dillerden Belge Nesne Modeli'nin kullanabileceği tipleri ve özellikleri kullanarak
çekirdek DOM'yi tanımlayın.

• ECMAScript language bindings for DOM (DOM için ECMAScript dil


ilişkilendirmeleri): Bir JavaScript programcısıysanız ve kodunuz için DOM kullanmak
istiyorsanız, Düzey 3 Belge Nesne Modeli Çekirdeği tanımlarına ilişkin bu ek ilginizi
çekecektir.

• "Ajax: A new approach to Web applications" (Jesse James Garrett , Adaptive Path,
Şubat 2005): Ajax moniker teriminin ilk kez kullanıldığı bu makaleyi okuyun -- tüm
Ajax geliştiricileri bu makaleyi okumalıdır.

• developerWorks Web mimarisi alanı: Web oluşturma becerilerinizi makaleler,


senaryolar, forumlar, vb. araçlarla genişletin.

• developerWorks teknik etkinlikleri ve Web yayınları: Teknik geliştiricilere yönelik bu


yazılım brifinglerini takip edin.

Ürün ve teknoloji edinme

• Head Rush Ajax, Brett McLaughlin (O'Reilly Media, 2006): Bu makaledeki fikirleri
Head First yöntemiyle öğrenin.

• Java and XML, Second Edition (Brett McLaughlin, O'Reilly Media, Inc., 2001):
Yazarın XHTML ve XML dönüşümleriyle ilgili görüşlerini okuyun.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 106/129


• JavaScript: The Definitive Guide (David Flanagan, O'Reilly Media, Inc., 2001):
JavaScript ve dinamik Web sayfalarıyla çalışmaya ilişkin kapsamlı yönergeleri
inceleyin. Yayınlanacak olan yeni basımda Ajax ile ilgili iki yeni bölüm vardır.

• Head First HTML with CSS & XHTML (Elizabeth and Eric Freeman, O'Reilly Media,
Inc., 2005): Standartlaşmış HTML ve XHTML ve CSS'yi HTML'ye uygulamayla
ilgili daha fazla bilgi öğrenin.

• IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki


geliştirme projenizi oluşturun.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 107/129


Ajax'ta Uzmanlaşma, Bölüm 7:
İsteklerde ve yanıtlarda XML kullanılması
Ne zaman iyi, ne zaman kötü bir fikir olduğunu öğrenin

Düzey: Orta

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

10 Ekim 2006

Sıradan Ajax geliştiricileri bile Ajax içindeki x harfini ve bunun XML anlamına geldiğini fark
edecektir. XML, her tür programlama ortamındaki en yaygın veri biçimlerinden biridir ve
zamanuyumsuz uygulamalarda sunucu yanıtları açısından gerçek avantajlar sunar. Bu
makalede, sunucuların bir isteğe yanıt verirken nasıl XML gönderdiklerini görürsünüz.

Günümüzde, XML ile karşılaşmadan önemli bir programlama gerçekleştiremezsiniz.


XHTML'e geçmeyi düşünen bir Web sayfası tasarımcısı, JavaScript ile çalışan bir Web
programcısı, uygulama açıklayıcıları ve veri bağlama kullanan sunucu tarafındaki bir
programcı ya da XML tabanlı veritabanlarını inceleyen bir arka yüz geliştiricisi de olsanız
genişletilebilir biçimleme diliyle her yerde karşılaşırsınız. Dolayısıyla, XML'in Ajax'ın
temelini oluşturan teknolojilerden biri olduğunu düşünmek çok da şaşırtıcı değildir.

Ancak, bu düşünce, teknik gerçeklikten çok, Ajax uygulamalarında kullanılan temel nesneler
için yapılan kötü ad seçimlerini yansıtmaktadır (XMLHttpRequest). Diğer bir deyişle, çoğu
kişi, XMLHttpRequest nesnesinin her zaman XML kullandığını varsaydıklarından, XML'in
Ajax'ın temel bir parçası olduğunu düşünürler. Ancak durum böyle değildir ve bunun
nedenleri, bu makalenin birinci bölümünün konusudur. Aslında, Ajax uygulamalarının
çoğunda, XML'in çok nadiren göründüğünü fark edeceksiniz.

XML'in Ajax'ta gerçek kullanımları vardır ve XMLHttpRequest bunlara da olanak verir.


Sunucuya XML göndermenizi engelleyecek hiçbir şey yoktur. Bu dizinin önceki
makalelerinde, veri göndermek için düz metin ve ad/değer parametrelerini kullanmıştınız,
ancak XML de geçerli bir biçimdir. Bu makalede, bunu nasıl yapacağınız üzerinde duracağız.
Daha da önemlisi, istek formatınız için neden XML kullanabileceğinizi ve çoğu durumda,
neden kullanmamanız gerektiğini anlatacağım.

XML: Gerçekten de orada mı?

Ajax uygulamaları ve bunların XML kullanımlarıyla ilgili varsayımlarda bulunmak kolaydır;


hem teknoloji adı (Ajax) hem de kullandığı temel nesne (XMLHttpRequest) XML'in
kullanıldığını ima eder ve Ajax ile bağlantılı XML kullanımını her zaman duyarsınız. Ancak,
bu algılama tamamen yanlıştır ve zamanuyumsuz uygulamaların yazılması söz konusu
olduğunda malzemelerinizi gerçekten bilmek isterseniz, bu algılamanın yanlış olduğunu
bilmelisiniz -- ve daha da iyisi neden yanlış olduğunu bilmelisiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 108/129


XMLHttpRequest: Kötü adlar ve HTTP

Bir teknolojiyle ilgili olabilecek en kötü şeylerden birisi, teknolojinin çok popüler olması ve
temel parçalarını değiştirmenin imkansız hale gelmesidir. Ajax uygulamalarındaki temel
nesnelerden biri olan XMLHttpRequest için de durum böyledir. Bakıldığında, HTTP istekleri
üzerinden XML göndermek ya da bir çeşit XML biçiminde HTTP istekleri göndermek için
tasarlanmış gibi görünür. Adının ne ima ettiğine bakmadan, nesnesinin asıl yaptığı şey, bir
HTTP isteği göndermek için istemci kodunuza (genellikle Web sayfanızdaki JavaScript) bir
yol sağlamasıdır. Hepsi bu kadar; yaptığı başka bir şey yoktur.

Bu nedenle, XMLHttpRequest nesnesinin adını, HttpRequest ya da belki, yalnızca Request


gibi daha doğru bir şeyle değiştirmek iyi olurdu. Ancak, bugün milyonlarca geliştirici
uygulamalarında Ajax kullanıyor ve kullanıcıların çoğunun Internet Explorer 7.0 ya da
Firefox 1.5 gibi yeni tarayıcı sürümlerine geçmesinin yıllar süreceğini bildiğimiz için böyle
bir hareket olanaklı değil. Sonuç olarak nesneyi XMLHttpRequest adıyla kullanmanız
gerekiyor ve bunun kötü bir şekilde adlandırıldığını fark etmek de geliştiricilere kalıyor.

XMLHttpRequest nesnesini desteklemeyen bir tarayıcıyla (özellikle Windows üzerinde)


çalışırken bilinen en iyi son çare yöntemlerinden biri Microsoft IFRAME nesnesinin
kullanılmasıdır. XML, HTTP, hatta bir istek gibi bile görünmüyor değil mi? Açıkçası,
bunların hepsini içerebilir, ancak XMLHttpRequest nesnesinin, XML ya da HTTP ile ilgili
olmaktan çok, bir sayfanın yeniden yüklenmesine gerek kalmadan isteklerin yapılmasıyla
ilgili olduğu gerçeği açıkça ortaya konmalıdır.

İstekler HTTP'dir, XML değil

Başka bir yaygın hata da XML'in sahne arkasında bir şekilde kullanıldığını düşünmektir --
dürüst olmak gerekirse, eskiden ben de böyle düşünürdüm! Ancak, bu görüş, teknolojiyi
anlama açısından zayıflığımızı da gösterir. Bir kullanıcı tarayıcısını açıp sunucudaki bir Web
sayfası için istekte bulunmak üzere http://www.google.com ya da
http://www.headfirstlabs.com gibi şeyler yazar. http:// kısmını yazmasa bile tarayıcı,
tarayıcı adres çubuğundaki bu parçayı doldurur. Bu birinci parça -- http:// -- iletişim nasıl
oluştuğuyla ilgili, anlaşılması çok da zor olmayan bir ipucu sağlar: Hypertext Transfer
Protocol (Bağlantılı Metin Aktarımı İletişim Kuralı) yoluyla. Sunucuyla iletişim kurmak için
Web sayfanıza bir kod yazdığınızda, bu ister Ajax, ister normal biçimli bir POST, ister bir
metin bağlantısı kullansın, söz konusu olan HTTP'dir.

HTTPS: Yine HTTP

Web konusunda yeni olanlarınız,


https://intranet.nextel.com
gibi URL'leri merak ediyor
olabilirsiniz. https, güvenli
HTTP'dir ve sıradan Web
istekleri tarafından kullanılan
HTTP iletişim kuralının daha
güvenli bir biçimini kullanır. Bu
yüzden, her ne kadar meraklı
gözlerden uzak tutmak amacıyla

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 109/129


fazladan birkaç güvenlik katmanı
eklense de HTTPS'de söz konusu
olan yine HTTP'dir.

Tarayıcılar ve sunucular arasındaki tüm Web iletişiminin büyük bir kısmının HTTP üzerinden
olduğunu bildiğimizde, XMLHttpRequest tarafından gizli bir biçimde kullanılan aktarım ya da
teknolojinin XML olduğu düşüncesi çok da anlamlı olmaz. XML kesinlikle HTTP isteği
içinde gönderilebilir, ancak HTTP, çok net bir şekilde tanımlanmış bir standarttır ve yakın bir
zamanda da herhangi bir şekilde ortadan kalkacak gibi görünmemektedir. İsteğinizde özel
olarak XML kullanmıyorsanız ya da sunucu, yanıtı size XML biçiminde göndermiyorsa,
XMLHttpRequest nesnesinde düz eski HTTP'yi kullanmaktan başka yapmanız gereken bir şey
yoktur. Birisi size bir daha "Evet, buna XMLHttpRequest denmesinin nedeni, arkada XML
kullanmasıdır" dediğinde yalnızca gülümseyin ve sabırlı bir şekilde onlara HTTP'nin ne
olduğunu ve XML'in HTTP üzerinden gönderilebildiğini, ancak XML'in bir veri biçimi
olduğunu, bir aktarım iletişim kuralı olmadığını anlatın.

XML'in (gerçekten) kullanılması

Şimdiye kadar size XML'in Ajax içinde kullanılmadığı yerlerden söz ettim. Ancak, Ajax
içindeki x ve XMLHttpRequest içindeki XML gerçekliğini devam ettiriyor ve Web
uygulamalarında XML kullanmak için birkaç seçeneğiniz var. Bu bölümde temel seçeneklere
bakacak ve bu makalenin geri kalanında, bu konuda gerçekten ayrıntıya gireceksiniz.

XML seçenekleri

Zamanuyumsuz uygulamalarınızda iki temel XML uygulaması görürsünüz:

• Bir Web sayfasından sunucuya, XML biçiminde bir istek gönderme


• Web sayfanızda sunucudan XML biçiminde bir istek alma

Bunlardan birincisi -- XML biçiminde bir istek gönderme -- isteğinizi, API kullanarak ya da
yalnızca metin dizeleri oluşturarak, XML formatında sunucuya göndermenizi gerektirir. Bu
seçenekte, eldeki ana iş, isteğin XML kurallarıyla uyumlu ve sunucunun anlayabileceği bir
şekilde oluşturulmasıdır. Dolayısıyla, gerçekten XML biçimine odaklanmanız gerekir;
göndermek istediğiniz veriler elinizdedir ve tüm yapmanız gereken, bunları XML
semantiğiyle hazırlamaktır. Bu makalenin geri kalanı, Ajax uygulamalarınızda XML'in bu
kullanımı üzerinde odaklanır.

Bu seçeneklerin ikincisi -- XML biçiminde bir istek alma -- sunucudan bir yanıt almanızı ve
verileri XML'den çıkarmanızı gerektirir (yine bir API kullanarak ya da biraz kaba kuvvet
yaklaşımıyla). Bu durumda, sunucudan gelen veriler üzerinde odaklanırsınız ve verileri,
yapıcı bir şekilde kullanmak için XML'den çekip çıkarmanız gerekir. Bu dizinin bir sonraki
makalesinin konusu da budur ve o zaman bu konu ayrıntılarıyla ele alınacaktır.

Küçük bir uyarı

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 110/129


XML kullanımının ayrıntılarına girmeden önce size küçük bir uyarıda bulunayım: XML,
küçük, hızlı, alandan tasarruf etmenizi sağlayacak bir biçim değildir. Sonraki birkaç bölümde
ve bu dizinin bir sonraki makalesinde de göreceğiniz gibi XML'i bu bağlamda kullanmak için
önemli nedenler vardır ve XML, düz metin istekleri ve yanıtlarıyla karşılaştırıldığında
(özellikle yanıtlarda) bazı avantajlara sahiptir. Ancak, iletilerinize XML'in gerektirdiği tüm
biçim imlerini ve semantiği eklediğiniz için XML her zaman düz metinden daha fazla alan
kaplayacak ve daha yavaş olacaktır.

Bir masaüstü uygulaması gibi çalışan parlak ve hızlı bir uygulama yazmak istiyorsanız, XML,
başlamak için en iyi nokta olmayabilir. Düz metinle başlayıp, XML için belirli bir
gereksinimle karşılaşırsanız, bu harikadır; ancak, en baştan XML kullanırsanız,
uygulamanızın yanıt verebilirliğini yavaşlatmanız neredeyse kesin bir sonuçtur. Çoğu
durumda, düz metni göndermek -- name=jennifer gibi ad/değer çiftlerini kullanmak -- metni,
aşağıdaki gibi XML'e çevirmekten daha hızlı olacaktır:

<name>jennifer</name>

XML'in zaman kaybettirdiği tüm yerleri bir düşünün: Metnin XML olarak hazırlanması;
fazladan bilgilerin gönderilmesi (dikkat ederseniz çevre öğeleri, XML üstbilgisini ya da daha
gerçekçi bir isteğin parçası olabilecek başka şeyleri belirtmedim); sunucunun XML'i
ayrıştırması, bir yanıt oluşturulması, yanıtın yeniden XML olarak hazırlanması ve Web
sayfanıza geri gönderilmesi; son olarak yanıtın sayfanızda ayrıştırılması ve verilerin
kullanılması. Dolayısıyla, XML'i ne zaman kullanacağınızı öğrenin, ancak birçok durumda
uygulamanızı daha hızlı yapacağını düşünerek uygulamanızı oluşturmaya XML'den
başlamayın; XML, daha çok, birazdan da sözünü edeceğimiz gibi esneklik sağlar.

İstemciden sunucuya XML

XML'i, bir istemciden sunucuya veri göndermek için kullanılan format olarak ele alalım.
Öncelikle, bunun teknik açıdan nasıl yapılacağını görecek, daha sonra da bunun ne zaman iyi
bir fikir olduğu ve ne zaman olmadığı üzerinde duracağız.

Ad/değer çiftlerinin gönderilmesi

Yazdığınız Web uygulamalarının yaklaşık %90'ında, kodunuzu sunucuya gönderilecek


ad/değer çiftleriyle bitirirsiniz. Örneğin, bir kullanıcı Web sayfanızdaki bir forma adını ve
adresini yazarsa, formdaki verileri aşağıdaki şekilde alabilirsiniz:

firstName=Larry
lastName=Gullahorn
street=9018 Heatherhorn Drive
city=Rowlett
state=Texas
zipCode=75080

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 111/129


Bu verileri sunucuya göndermek için yalnızca düz metin kullanıyorsanız, kodunuz Liste
1'deki gibi görünebilir. (Bu, bu dizinin birinci makalesinde kullanılan örnek I'e benzer bir
örnektir. Bkz. Kaynaklar.)

Liste 1. Ad/değer çiftlerinin düz metin olarak gönderilmesi


function callServer() {
// Get the city and state from the Web form
var firstName = document.getElementById("firstName").value;
var lastName = document.getElementById("lastName").value;
var street = document.getElementById("street").value;
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
var zipCode = document.getElementById("zipCode").value;

// Build the URL to connect to


var url = "/scripts/saveAddress.php?firstName=" + escape(firstName) +
"&lastName=" + escape(lastName) + "&street=" + escape(street) +
"&city=" + escape(city) + "&state=" + escape(state) +
"&zipCode=" + escape(zipCode);

// Open a connection to the server


xmlHttp.open("GET", url, true);

// Set up a function for the server to run when it's done


xmlHttp.onreadystatechange = confirmUpdate;

// Send the request


xmlHttp.send(null);
}

Ad/değer çiftlerinin XML'e dönüştürülmesi

Bunun gibi veriler için biçim olarak XML kullanmayı istiyorsanız, yapmanız gereken ilk şey
verileri saklamak için temel XML biçimini kullanmak olacaktır. Ad/değer çiftlerinizin tümü
XML öğelerine dönüştürülebilir; burada, öğe adı çiftin adı ve öğenin içeriği de değer olur:

<firstName>Larry</firstName>
<lastName>Gullahorn</lastName>
<street>9018 Heatherhorn Drive</street>
<city>Rowlett</city>

<state>Texas</state>
<zipCode>75080</zipCode>

Elbette, XML bir kök öğenizin ya da yalnızca bir belge parçasıyla çalışıyorsanız (XML
belgesinin bir parçası) çevreleyen bir öğenin olmasını gerektirir. Dolayısıyla, yukarıdaki
XML'i aşağıdaki gibi bir koda dönüştürebilirsiniz:

<address>
<firstName>Larry</firstName>
<lastName>Gullahorn</lastName>
<street>9018 Heatherhorn Drive</street>

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 112/129


<city>Rowlett</city>
<state>Texas</state>
<zipCode>75080</zipCode>
</address>

Şimdi bu yapıyı Web istemcinizde oluşturmaya ve sunucuya göndermeye -- neredeyse --


hazırsınız.

Sözlü iletişim

Ağ üzerinden XML göndermeye başlamadan önce, verileri gönderdiğiniz sunucunun -- ve


komut dosyasının -- gerçekten de XML'i kabul ettiğinden emin olmak istiyorsunuz.
Birçoğunuz için bu, aptalca da olsa yapılması gereken bir nokta gibi görünebilir; ancak, yeni
programcıların çoğu, ağ üzerinden XML gönderirlerse, bunun doğru biçimde alınacağını ve
yorumlanacağını varsayarlar.

Aslında, XML biçiminde gönderdiğiniz verilerin doğru olarak alındığından emin olmak için
gerçekleştirmeniz gereken iki adım vardır:

1. XML'i gönderdiğiniz komut dosyasının veri biçimi olarak XML'i kabul ettiğinden
emin olun.
2. Komut dosyasının, verilerinizi gönderdiğiniz belirli XML biçimini ve yapısını kabul
ettiğinden emin olun.

Bunların ikisi de gerçekten bir insanla konuşmanızı gerektirebilir, sizi bu konuda uyarıyorum!
XML olarak veri gönderebilmeniz önem taşıyorsa, komut dosyası yazarlarının çoğu size
iyilikte bulunur; bu nedenle, XML kabul edecek bir komut dosyası bulmak çok da zor
değildir. Yine de, kullandığınız biçimin komut dosyasının beklediği biçimle eşleştiğinden
emin olmanız gerekir. Örneğin, sunucunun aşağıdaki gibi verileri kabul ettiğini düşünün:

<profile>
<firstName>Larry</firstName>
<lastName>Gullahorn</lastName>
<street>9018 Heatherhorn Drive</street>

<city>Rowlett</city>
<state>Texas</state>
<zip-code>75080</zip-code>
</profile>

Bu, yukarıdaki XML'e benzer -- iki nokta dışında:

1. İstemciden gelen XML bir address öğesi içinde olmasına rağmen sunucu, verilerin
bir profile öğesi içinde bulunmasını beklemektedir.
2. İstemciden gelen XML zipCode öğesini kullanır, ancak sunucu, posta kodunun bir
zip-code öğesinde olmasını beklemektedir.

Büyük bir sistem içinde bu gerçekten küçük noktalar, verilerinizi kabul eden ve işleyen
sunucu ile kötü bir şekilde çöken ve Web sayfanıza -- ve büyük olasılıkla kullanıcılara --
şifreli bir hata iletisi veren sunucu arasındaki farkı oluşturur. Bu nedenle, sunucunun neyi

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 113/129


beklediğini anlamalı ve verileri bu biçime uygun hale getirmelisiniz. Daha sonra -- yalnızca o
zaman -- XML'in bir istemciden sunucuya gönderilmesi konusunda gerçek teknik sorunlarla
uğraşmaya hazır olursunuz.

XML'in sunucuya gönderilmesi

XML'i sunucuya gönderme söz konusu olduğunda, verilerinizi almak ve XML'e


dönüştürürken, verilerinizi gerçekten iletmek için harcadığınızdan daha fazla kod harcarsınız.
Aslında, XML dizesini sunucuya göndermek üzere hazırladıktan sonra bu işlemi, diğer
herhangi bir düz metni gönderdiğiniz şekilde gerçekleştirirsiniz; bu işlemi görmek için Liste
2'ye bakın.

Liste 2. Ad/değer çiftlerinin XML olarak gönderilmesi


function callServer() {
// Get the city and state from the Web form
var firstName = document.getElementById("firstName").value;
var lastName = document.getElementById("lastName").value;
var street = document.getElementById("street").value;
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
var zipCode = document.getElementById("zipCode").value;

var xmlString = "<profile>" +


" <firstName>" + escape(firstName) + "</firstName>" +
" <lastName>" + escape(lastName) + "</lastName>" +
" <street>" + escape(street) + "</street>" +
" <city>" + escape(city) + "</city>" +
" <state>" + escape(state) + "</state>" +
" <zip-code>" + escape(zipCode) + "</zip-code>" +
"</profile>";

// Build the URL to connect to

var url = "/scripts/saveAddress.php";

// Open a connection to the server


xmlHttp.open("POST", url, true);

// Tell the server you're sending it XML


xmlHttp.setRequestHeader("Content-Type", "text/xml");

// Set up a function for the server to run when it's done


xmlHttp.onreadystatechange = confirmUpdate;

// Send the request


xmlHttp.send(xmlString);
}

Bu kodun çoğu, üzerinde durulmaya değer birkaç nokta dışında, kendi kendini açıklar
niteliktedir. Birincisi, isteğinizdeki verilerin el ile XML olarak biçimlendirilmesi gerekir.
Belge Nesne Modeli'nin (DOM) kullanımına ilişkin üç makaleden sonra bu biraz hayal
kırıklığına neden olmuştur sanırım, değil mi? Hiçbir şey JavaScript kullanan bir XML
belgesini oluştururken DOM kullanmanızı engellemez; bu durumda, GET ya da POST
isteğiyle ağ üzerinden göndermeden önce DOM nesnesini metne dönüştürmeniz gerekir. Bu

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 114/129


nedenle, verileri olağan dize işlemiyle basitçe biçimlendirmek çok daha kolay olur. Elbette,
hata ve yazım yanlışları ortaya çıkabileceğinden XML ile uğraşan bir kod yazarken daha da
dikkatli olmanız gerekir.

XML'inizi oluşturduktan sonra, büyük oranda metni gönderirken açtığınıza benzer bir
bağlantı açarsınız. Bazı tarayıcılar GET sorgu dizelerine uzunluk sınırlaması getirdiği ve
XML de oldukça uzun olabildiği için ben, XML için POST isteklerini kullanmayı tercih
ediyorum; Liste 2'de GET isteğinden uygun şekilde POST isteğine nasıl geçildiğini
görebilirsiniz. Ayrıca, istekte bulunduğunuz URL'nin sonuna eklenen bir parametre olarak
gönderilmek yerine XML, send() yöntemiyle gönderilir. Bunların tümü oldukça küçük
farklılıklardır ve ayarlanmaları kolaydır.

Yine de tamamen yeni bir kod satırı yazmanız gerekir:

xmlHttp.setRequestHeader("Content-Type", "text/xml");

Bunu anlamak çok da zor değil: Yalnızca sunucuya düz eski ad/değer çiftleri göndermek
yerine XML gönderdiğinizi belirtir. Her iki durumda da verileri metin olarak gönderirsiniz,
ancak burada text/xml olarak kullanırken, diğerinde gönderilen XML düz metin olarak
kullanılır. Az önce ad/değer çiftlerini kullandıysanız bu satır şöyle okunur:

xmlHttp.setRequestHeader("Content-Type", "text/plain");

Sunucuya, XML gönderdiğinizi bildirmeyi unutursanız sorun yaşayabilirsiniz, bu nedenle bu


adımı unutmayın.

Bunların hepsini bir araya getirdikten sonra, yapmanız gereken tek şey send() yöntemini
çağırmak ve XML dizesini geçirmektir. Sunucu XML isteğinizi alır ve (ön çalışmanızı
yaptığınızı varsayarak) XML'i kabul eder, ayrıştırır ve size bir yanıt gönderir. Her şey bundan
ibarettir -- birkaç kod değişikliği yapılmış XML istekleri.

XML gönderilmesi: İyi mi, kötü mü?

XML yanıtları için XML isteklerini (ve bu makaleyi) terk etmeden önce, isteklerinizdeki
XML kullanımının hassasiyeti üzerinde biraz duralım. XML'in aktarım açısından hiçbir
şekilde en hızlı veri biçimi olmadığından söz etmiştim, ancak üzerinde düşünülmesi gereken
daha birçok nokta var.

XML'in oluşturulması basit değildir

Fark etmeniz gereken ilk şey, XML'in isteklerde kullanmak üzere kolayca oluşturabileceğiniz
bir şey olmadığıdır. Liste 2'de gördüğünüz gibi verileriniz, XML semantiğiyle hızlı bir şekilde
karmaşıklaşabilir:

var xmlString = "<profile>" +


" <firstName>" + escape(firstName) + "</firstName>" +

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 115/129


" <lastName>" + escape(lastName) + "</lastName>" +
" <street>" + escape(street) + "</street>" +
" <city>" + escape(city) + "</city>" +
" <state>" + escape(state) + "</state>" +
" <zip-code>" + escape(zipCode) + "</zip-code>" +
"</profile>";

Bu çok kötü görünmeyebilir, ancak bunun yalnızca altı alanı olan bir XML parçası olduğu da
unutulmamalıdır. Geliştireceğiniz Web formlarının çoğunda 10 - 15 arasında alan olacaktır;
tüm isteklerinizde Ajax kullanmasanız da, bu noktayı göz önünde bulundurun. En azından
gerçek verilerle harcadığınız kadar zamanı köşeli ayraçlarla ve biçim imi adlarıyla harcarsınız
ve küçük hatalar yapma olasılığınız oldukça yüksektir.

Buradaki başka bir sorun da -- önceden de belirttiğim gibi -- bu XML'i el ile oluşturmanız
gerektiğidir. Bir DOM nesnesini, istek olarak gönderebileceğiniz bir dizeye dönüştürmek için
iyi ve basit yöntemler olmadığı için DOM'nin kullanılması iyi bir seçenek değildir. Bu
nedenle, bunun gibi dizelerle çalışmak en iyisidir -- ancak bu, aynı zamanda yeni geliştiriciler
için gerçekleştirilmesi ve anlaşılması en zor seçenektir. Bu örnekte, tüm XML'i tek bir satırda
oluşturdunuz; bunu birkaç adımda yaptığınızda her şey daha karmaşıklaşır.

XML, isteklerinize hiçbir şey eklemez

Karmaşıklık sorununun ötesinde, istekleriniz için XML kullanmak, düz metin ve ad/değer
çiftleriyle karşılaştırıldığında size gerçekten fazla avantaj (sağlayacağı herhangi bir avantaj
varsa) sağlayacak değildir. Bu makaledeki her şeyin, ad/değer çiftlerini kullanarak
gönderebileceğiniz verilerle aynı verileri almaya (Liste 1'e bakın) ve bunları XML ile
göndermeye odaklandığını düşünün. Hiçbir noktada XML ile gönderebileceğiniz bir şeyi düz
metin kullanarak gönderemeyeceğiniz belirtilmedi; bunun nedeni, hemen hemen hiçbir zaman
XML kullanarak gönderebileceğiniz bir şeyi düz metin kullanarak gönderememenizin söz
konusu olmamasıdır.

Ve bu, gerçekten de XML ve istekler ile ilgili ana noktadır: Çok seyrek olarak bunu
yapmanızı gerektirecek bir durumla karşılaşırsınız. Bu dizinin bir sonraki makalesinde, bir
sunucunun düz metin kullanarak yaparken çok zorlanacağı bazı şeyleri yapmak için XML
kullanabileceğini göreceksiniz; ancak, istekler söz konusu olduğunda bu durum geçerli
değildir. Yalnızca XML kabul eden bir komut dosyasından söz etmiyorsanız (çok az da olsa
bunlardan var), hemen her istek durumunda düz metin kullanmanız daha iyi olacaktır.

Sonuç

Kesinlikle Ajax içindeki XML'i anlamaya başladığınızı hissediyor olmalısınız. Ajax


uygulamalarının XML'i kullanmak zorunda olmadıklarını ve XML'in veri aktarımı için bir
çeşit sihirli araç olmadığını biliyorsunuz. Bir Web sayfasından bir sunucuya XML gönderme
konusunda da oldukça rahat olmalısınız. Daha da önemlisi, bir sunucunun isteklerinizi
gerçekten işleyeceğinden ve yanıtlayacağından emin olmak için neler yapılması gerektiğiniz
biliyorsunuz: Sunucu komut dosyasının XML'i ve XML'in verileri gönderdiğiniz biçimini
kabul ettiğinden emin olmalısınız.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 116/129


XML'in neden isteklere ilişkin veri biçimi için her zaman harika bir seçim olmadığı
konusunda da artık iyi bir fikriniz olmalı. Gelecek makalelerde, XML'in yardımcı olduğu bazı
durumları, ancak çoğu istekte, her şeyi yavaşlattığını ve karmaşıklaştırdığını göreceksiniz.
Dolayısıyla, genellikle bir makalede öğrendiklerinizi hemen kullanmaya başlamanızı
önerdiğim halde, burada öğrendiklerinizi kullanma konusunda çok dikkatli olmanızı
öneriyorum. Ajax uygulamalarında XML isteklerinin yeri vardır, ancak bu yer, düşündüğünüz
kadar geniş değildir.

Bu dizinin bir sonraki makalesinde, sunucuların XML kullanarak nasıl yanıt verdiklerini ve
Web uygulamalarınızın bu yanıtları nasıl işleyebildiklerini göreceksiniz. Neyse ki, bir
sunucunun Web uygulamasına XML göndermesi için, bunun tam tersinden daha çok sayıda
neden vardır; bu yüzden, o makalenin teknik ayrıntılarını daha fazla kullanacaksınız; şimdilik,
XML'in neden her zaman harika bir fikir olmadığını (en azından istekleri gönderirken)
anladığınızdan emin olun. İsteklere ilişkin veri biçimi olarak XML kullanan bazı Web
uygulamalarını denemek ve gerçekleştirmek ve daha sonra düz metne dönmek ve hangisinin
sizin için daha hızlı ve kolay geldiğini belirlemek isteyebilirsiniz. Bir sonraki makaleye kadar
çevrimiçi kalın.

Kaynaklar

Bilgi Edinme

• Ajax'ta Uzmanlaşma: Bu dizinin önceki makalelerini okuyun.

• XML: Çeşitli teknik makaleler ve ipuçları, senaryolar, standartlar ve IBM Redbook


yayınları için developerWorks XML Zone sitesine bakın.

• xml.com: Deneyimli bir XML programcısı değilseniz, XML konusunda anlaması en


kolay çevrimiçi kaynaklardan biriyle başlayın.

• "Build dynamic Java applications" (Philip McCarthy, developerWorks, Eylül 2005):


Java™ bakış açısıyla Ajax'a sunucu tarafından bir bakış.

• "Java object serialization for Ajax" (Philip McCarthy, developerWorks, Ekim 2005):
Ağ üzerinden nesne gönderme ve Ajax ile etkileşimde bulunma konularını Java bakış
açısıyla inceler.

• "Call SOAP Web services with Ajax" (James Snell, developerWorks, Ekim 2005):
Ajax'ın var olan SOAP tabanlı Web hizmetleriyle bütünleştirilmesine ilişkin bu ileri
düzey makaleyi inceleyin; Ajax tasarım şablonunu kullanarak Web tarayıcısı tabanlı
SOAP hizmetleri istemcisini nasıl uygulayacağınızı gösterir.

• World Wide Web Consortium'daki DOM Ana Sayfası: DOM ile ilgili her şeyin
başlangıç noktasını ziyaret edin.

• DOM Level 3 Core Specification (DOM Düzey 3 Çekirdek Belirtimi): Çeşitli


dillerden Belge Nesne Modeli'nin kullanabileceği tipleri ve özellikleri kullanarak
çekirdek DOM'yi tanımlayın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 117/129


• ECMAScript language bindings for DOM (DOM için ECMAScript dil
ilişkilendirmeleri): Bir JavaScript programcısıysanız ve kodunuz için DOM kullanmak
istiyorsanız, Düzey 3 Belge Nesne Modeli Çekirdeği tanımlarına ilişkin bu ek ilginizi
çekecektir.

• "Ajax: A new approach to Web applications" (Jesse James Garrett , Adaptive Path,
Şubat 2005): Ajax moniker teriminin ilk kez kullanıldığı bu makaleyi okuyun -- tüm
Ajax geliştiricileri bu makaleyi okumalıdır.

• developerWorks teknik etkinlikleri ve Web yayınları: Teknik geliştiricilere yönelik bu


yazılım brifinglerini takip edin.

• developerWorks Web geliştirme alanı: Web oluşturma becerilerinizi makaleler,


senaryolar, forumlar, vb. araçlarla genişletin.

Ürün ve teknoloji edinme

• Head Rush Ajax, Brett McLaughlin (O'Reilly Media, 2006): Bu makaledeki fikirleri
Head First yöntemiyle öğrenin.

• Java and XML, Second Edition (Brett McLaughlin, O'Reilly Media, Inc., 2001):
Yazarın XHTML ve XML dönüşümleriyle ilgili görüşlerini okuyun.

• JavaScript: The Definitive Guide (David Flanagan, O'Reilly Media, Inc., 2001):
JavaScript ve dinamik Web sayfalarıyla çalışmaya ilişkin kapsamlı yönergeleri
inceleyin. Yayınlanacak olan yeni basımda Ajax ile ilgili iki yeni bölüm vardır.

• Head First HTML with CSS & XHTML (Elizabeth and Eric Freeman, O'Reilly Media,
Inc., 2005): Standartlaşmış HTML ve XHTML ve CSS'yi HTML'ye uygulamayla
ilgili daha fazla bilgi öğrenin.

• IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki


geliştirme projenizi oluşturun.

Tartışma

• developerWorks Web günlükleri: DeveloperWorks topluluğuna katılın.

• Ajax forum on developerWorks: AJAX'ı yeni öğrenen ya da etkin olarak kullananWeb


geliştiricilerinden oluşan bu forumda yeni bilgiler öğrenin, düşüncelerinizi tartışın,
bildiklerinizi paylaşın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 118/129


Ajax'ta Uzmanlaşma, Bölüm 8:
İsteklerde ve yanıtlarda XML kullanılması
Ajax istemci/sunucu iletişimi hassas bir iş olabilir

Düzey: Orta

Brett McLaughlin (brett@newInstance.com), Yazar ve Editör, O'Reilly Media Inc.

07 Kasım 2006

Bu dizinin son makalesinde, Ajax uygulamalarınızın sunucuya gönderilen istekleri nasıl XML
şeklinde biçimlendirebildiğini gördünüz. Çoğu durumda, bunun neden iyi bir fikir olmadığını
da okudunuz. Bu makale, genellikle daha iyi bir fikir olan bir şey üzerine odaklanır: İstemciye
XML yanıtlarının gönderilmesi.

Esas olarak yapmamanız gereken şeylerle ilgili makaleler yazmaktan gerçekten


hoşlanmıyorum. Böyle makaleler çoğu kez yazılması anlamsız olan şeyleri içerir. Makalenin
yarısı bir şeyi açıklamakla geçer, makalenin kalan kısmında da, az önce öğrendiğiniz
teknikleri kullanmanın ne kadar kötü bir fikir olduğunu açıklanır. Geçen ayki makale de
büyük oranda böyle bir yazıydı (okuma fırsatı bulamadıysanız, Kaynaklar içinde verilen
bağlantıyı izleyin). Bu yazıda size, Ajax uygulamalarınızın isteklerinde veri biçimi olarak
XML'i nasıl kullanacağınız öğretildi.

Bu makalenin, XML isteklerini öğrenmek için harcadığınız zamanı geri kazanmanızı


sağlayacağını umuyorum. Ajax uygulamalarında veri gönderme biçimi olarak XML
kullanmanın çok az nedeni varken, bir sunucunun istemciye XML geri göndermesini
istemeniz için de birçok neden vardır. Son makalede XML ile ilgili öğrendiğiniz her şey, bu
makalede biraz değer kazanmaya başlayacak.

Sunucular çok şey söyleyemez (bazen)

Bir sunucudan XML yanıtı almaya ilişkin teknik ayrıntılara girmeden önce, bir sunucunun bir
isteğe yanıt olarak XML göndermesinin neden bu kadar iyi bir fikir (ve bunun, bir istemcinin
bu isteği XML olarak göndermesinden nasıl farklı) olduğunu anlamanız gerekir.

İstemciler ad/değer çiftleriyle konuşur

Son makaleden de hatırlayacağınız gibi, istemciler isteklerini ad/değer çiftlerini kullanarak


gönderebildikleri için çoğu durumda XML kullanmalarına gerek yoktur. Şöyle bir ad
gönderebilirsiniz: name=jennifer. Ardışık ad/değer çiftleri arasına bir ve (&) işareti ekleyerek
bunları birleştirebilirsiniz (name=jennifer&job=president gibi). Basit metin ve bu ad/değer
çiftlerini kullanarak, istemciler birden çok değere sahip istekleri sunucuya kolayca
gönderebilir. XML'in sağladığı ek yapıya (ve ek yüke) nadiren gereksinim duyulur.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 119/129


Aslında, bir sunucuya XML göndermenizi gerektirecek neredeyse tüm nedenler iki temel
kategoride gruplanabilir:

• Sunucu yalnızca XML isteklerini kabul ediyordur. Bu durumlarda, başka bir


seçeneğiniz yoktur. Geçen ayki makalenin temel noktaları, bu tür istekleri göndermek
için gereksinim duyacağınız tüm araçları sağlamış olmalıdır.
• Yalnızca XML ya da SOAP isteklerini kabul eden bir uzak API
çağırıyorsunuzdur. Bu, gerçekten de önceki noktanın biraz daha özel bir durumudur,
ancak kendi başına söz etmeye değer bir noktadır. Google ya da Amazon'daki API'leri
bir zamanuyumsuz istekte kullanmak isterseniz, bazı konuları göz önünde
bulundurmanız gerekir. Bunlara ve bunun gibi API'lere istek gönderilmesine ilişkin
birkaç örneğe gelecek ayın makalesinde değineceğim.

Sunucular ad/değer çiftlerini gönderemez (standart şekilde)

Ad/değer çiftleri gönderdiğinizde, istekleri gönderen Web tarayıcısı ve bu isteğe yanıt veren
ve bir sunucu programını barındıran platform bu ad/değer çiftlerini, bir sunucu programının
kolayca çalışabileceği verilere dönüştürmek için birlikte çalışır. Neredeyse her sunucu tarafı
teknolojisi -- Java™ sunucu uygulamalarından PHP'ye, Perl'e, Ruby on Rails'e -- bir ada
dayalı değerleri almanız için çeşitli yöntemler çağırmanızı sağlar. Dolayısıyla, name
özniteliğinin alınması önemsizdir.

Diğer yönde farklı bir durum söz konusudur. Sunucu, name=jennifer&job=president


dizesinin bulunduğu bir uygulamaya yanıt verdiyse, istemcide iki ad/değer çiftini ayırmak ve
daha sonra her bir çifti bir ad ve değere bölmek için standartlaştırılmış, kolay bir yöntem
bulunmaz. Döndürülen verileri el ile ayrıştırmanız gerekir. Sunucu, ad/değer çiftlerinden
oluşan bir yanıt döndürürse, bu yanıt, noktalı virgüllerle ya da çubuk simgeleriyle ya da diğer
standart dışı biçimlendirme karakterleriyle birbirinden ayrılmış öğelerden oluşan bir yanıtı
yorumlamaktan daha kolay (ya da daha zor) değildir.

Bana biraz yer açın!

Çoğu HTTP isteğinde, tek bir


boşluğu göstermek için kaçış sırası
olarak %20 kullanılır. Dolayısıyla,
"Live Together, Die Alone" metni,
HTTP üzerinden
Live%20Together,%20Die%20Alone
olarak gönderilir.

Bu durumda karşılaşacağınız sorun, yanıtlarınızda düz metin kullanmanızın ve istemcinin bu


yanıtı alıp standart bir yolla yorumlamasının (en azından yanıt birden çok değer içerdiğinde)
kolay bir yolunun olmamasıdır. Örneğin, sunucunuz yalnızca 42 sayısını geri gönderseydi,
düz metin harika olurdu. Peki, TV'deki dizilere (Lost, Alias ve Six Degrees) ilişkin en son
seyredilme oranlarını bir defada gönderirse ne olur? Bu yanıtı düz metin kullanarak
göndermeye ilişkin birçok yol seçebilirsiniz (birkaç örnek için bkz. Liste 1), ancak hiçbiri,
istemcide bir çalışma yapılmadan kolayca yorumlanamaz ve hiçbir tamamen standartlaşmış
değildir.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 120/129


Liste 1. TV seyredilme oranlarına ilişkin sunucu yanıtı (çeşitli sürümler)
show=Alias&ratings=6.5|show=Lost&ratings=14.2|show=Six%20Degrees&ratings=9.1

Alias=6.5&Lost=14.2&Six%20Degrees=9.1

Alias|6.5|Lost|14.2|Six%20Degrees|9.1

Bu yanıt dizelerinin nasıl ayrılacağını anlamak çok zor olmasa da, bir istemcinin, noktalı
virgüllere, eşittir işaretlerine, çubuklara ve "ve" işaretlerine dayanarak dizeyi ayrıştırması ve
bölmesi gerekir. Bu, diğer geliştiricilerin kolayca anlayabileceği ve sağlayabileceği güçlü bir
kod yazmak için nadiren kullanılan bir yoldur.

XML girin

Bu sunucunun istemcilere ad/değer çiftleriyle yanıt vermesi için standart bir yol olmadığını
fark ettiğinizde, XML kullanmanın arkasında yatan mantık netleşmeye başlar. Sunucuya veri
gönderirken, sunucular ve sunucu tarafında diller çiftleri kolayca yorumlayabildiği için
ad/değer çiftleri harika birer seçimdir; istemciye veri döndürürken de XML kullanmak için
aynı şey geçerlidir. Birkaç makale önce, XML'i ayrıştırmak için DOM'nin nasıl kullanıldığını
görmüştünüz ve sonraki bir makalede XML'i ayrıştırmak için JSON'nin da başka bir seçenek
sunduğunu göreceksiniz. Hepsinin üzerinde, XML'i düz metin gibi işleyebilir ve değerleri, bu
şekilde alabilirsiniz. Dolayısıyla, bir sunucudan XML yanıtı almanın ve oldukça
standartlaşmış kodla verileri çıkarmanın ve bir istemcide kullanmanın birkaç yolu vardır.

Ek bir bonus olarak XML'in anlaşılması genellikle oldukça kolaydır. Örneğin, programlama
yapabilen kişilerin çoğu, Liste 2'deki verileri anlayabilir.

Liste 2. TV seyredilme oranlarına ilişkin sunucu yanıtı (XML)


<ratings>
<show>
<title>Alias</title>
<rating>6.5</rating>

</show>
<show>
<title>Lost</title>
<rating>14.2</rating>
</show>

<show>
<title>Six Degrees</title>
<rating>9.1</rating>
</show>
</ratings>

Liste 2'de, belirli bir noktalı virgül ya da kesme işaretinin anlamıyla ilgili herhangi bir gizemli
nokta yoktur.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 121/129


Sunucudan XML alınması

Bu dizinin odak noktası Ajax denkleminin istemci tarafı olduğundan, sunucu tarafındaki bir
programın yanıtı XML olarak nasıl oluşturduğu üzerinde ayrıntılı bilgi vermeyeceğim. Ancak,
istemciniz XML aldığında bazı özel konuları bilmeniz gerekir.

Birincisi, sunucudan gelen bir XML yanıtını iki temel şekilde işleyebilirsiniz:

• XML olarak biçimlendirilen düz metin


• DOM Document nesnesiyle gösterilen bir XML belgesi.

İkincisi, örnek olsun diye bir sunucudan basit bir XML yanıtı aldığınızı varsayın. Liste 3'te
yukarıda ayrıntılı olarak verilen aynı TV listesi gösterilmektedir (aslında bu, sizin için
yeniden yazılan, Liste 2'dekiyle aynı XML'dir). Bu bölümdeki konularda bu örnek XML'i
kullanacağım.

Liste 3. Örnek olarak XML biçimli TV seyredilme oranları


<ratings>
<show>
<title>Alias</title>
<rating>6.5</rating>

</show>
<show>
<title>Lost</title>
<rating>14.2</rating>
</show>

<show>
<title>Six Degrees</title>
<rating>9.1</rating>
</show>
</ratings>

XML ile düz metin olarak çalışma

En azından yeni programlama tekniklerini öğrenme açısından, XML'i işlemenin en kolay


seçeneği, XML'i sunucudan dönen herhangi bir metin parçası gibi ele almaktır. Diğer bir
deyişle, veri biçimini dikkate almaz ve yalnızca sunucudan gelen yanıtı alırsınız.

Bu durumda, sunucunun size XML olmayan bir yanıt gönderdiğinde yapacağınız gibi istek
nesnenizin responseText özelliğini kullanırsınız (bkz. Liste 4).

Liste 4. XML'nin olağan bir sunucu yanıtı olarak işlenmesi


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText;

// response has the XML response from the server


alert(response);

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 122/129


}
}
}

Önceki makaleleri gözden geçirin

Çok sayıda kod yinelemesini önlemek için, dizinin


sonraki makalelerinde yalnızca anlatılan konuyla
ilgili kod kısımları gösterilmektedir. Bu nedenle,
Liste 4'te yalnızca Ajax istemcisi kodunuzdaki geri
arama yöntemi gösterilmiştir. Bu yöntemin
zamanuyumsuz bir uygulamanın daha geniş
bağlamına nasıl uyacağı konusunda şüpheleriniz
varsa, dizinin, Ajax uygulamalarının temel
noktalarını kapsayan ilk birkaç makalesini gözden
geçirin. Bu eski makalelere ilişkin bağlantılar için
Kaynaklar bölümüne bakın.

Bu kod parçasında, updatePage() geri çağrı ve request, XMLHttpRequest nesnesidir. XML


yanıtı, response değişkeninde tümü bir arada dizilmiş bir şekilde ortaya çıkar. Bu değişkeni
yazdırdıysanız, Liste 5'tekine benzer bir kod görmeniz gerekir. (Liste 5'teki kodun tek, sürekli
bir satır olduğuna dikkat edin. Burada, görüntülenebilmesi amacıyla birden çok satırda
gösterilmiştir.)

Liste 5. Yanıt değişkeninin değeri


<ratings><show><title>Alias</title><rating>6.5</rating>
</show><show><title>Lost</title><rating>14.2</rating></show><show>
<title>Six Degrees</title><rating>9.1</rating></show></ratings>

Burada belirtilmesi gereken en önemli şey, XML'in tamamının birlikte çalıştığıdır. Çoğu
durumda, sunucular XML'i boşluklar ve satır başlarıyla biçimlendirmez; Liste 5'te
gördüğünüz gibi tümünü tek bir dize halinde birleştirir. Elbette, uygulamalarınız boşluklarla
çok ilgilenmediği için bu, bir sorun oluşturmaz; ancak, okumak biraz zorlaşır.

Bu noktada, bu verileri ayırmak için JavaScript split işlevini ve öğe adlarını ve değerlerini
almak için temel dize işlemesini kullanabilirsiniz. Tabii ki bu, size gerçekten sıkıntı verecektir
ve böyle bir durumda, dizinin önceki makalelerinde DOM'ye (Belge Nesne Modeli) bakmak
için çok zaman harcadığınız gerçeği göz ardı edilir. Bu nedenle, responseText ile bir
sunucunun XML yanıtını kolayca kullanabileceğinizi ve çıkarabileceğinizi aklınızda
tutmanızı öneririm, ancak size daha fazla kod göstermeyeceğim; biraz sonra da göreceğiniz
gibi, DOM'yi kullanabileceğiniz durumlarda, XML verilerini almak için bu yaklaşımı
kullanmamanız gerekir.

XML'in XML olarak işlenmesi

Sunucunun XML biçimli yanıtını diğer metin yanıtları gibi işleyebilirsiniz, ancak bunu
yapmanızı gerektiren herhangi bir neden yoktur. Birincisi, bu dizinin sadık bir okuruysanız,
XML'i işlemek için yararlanabileceğiniz JavaScript dostu bir API olan DOM'yi nasıl

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 123/129


kullanacağınızı biliyorsunuzdur. Daha da iyisi, JavaScript ve XMLHttpRequest nesnesi,
sunucunun XML yanıtını almak ve bunu, bir DOM Document nesnesi biçiminde almak için
mükemmel bir özellik sağlar.

Bunu çalışırken görmek için Liste 6'ya bakın. Bu kod, Liste 4'e benzer, ancak responseText
özelliğini kullanmak yerine, geri çağrı responseXML özelliğini kullanır. XMLHttpRequest
nesnesinde bulunan bu özellik, sunucunun yanıtını bir DOM belgesi biçiminde döndürür.

Liste 6. XML'in XML olarak işlenmesi


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var xmlDoc = request.responseXML;

// work with xmlDoc using the DOM


}
}
}

Artık bir DOM Document öğeniz var ve bununla, diğer herhangi bir XML ile yaptığınız gibi
çalışabilirsiniz. Örneğin, tüm show öğelerini alabilirsiniz (bkz. Liste 7).

Liste 7. Tüm show öğelerinin alınması


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var xmlDoc = request.responseXML;

var showElements = xmlDoc.getElementsByTagName("show");


}
}
}

DOM ile daha önce çalıştıysanız, bu size tanıdık gelmeye başlamış olmalı. Şimdiye kadar
öğrendiğiniz tüm DOM yöntemlerini kullanabilir ve sunucudan aldığınız XML'yi kolayca
işleyebilirsiniz.

Elbette, olağan JavaScript koduna da karıştırabilirsiniz. Örneğin, Liste 8'deki gibi tüm show
öğelerini yineleyebilirsiniz.

Liste 8. Tüm show öğelerinin yinelenmesi


function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var xmlDoc = request.responseXML;

var showElements = xmlDoc.getElementsByTagName("show");


for (var x=0; x<showElements.length; x++) {
// We know that the first child of show is title, and the second is

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 124/129


rating
var title = showElements[x].childNodes[0].value;
var rating = showElements[x].childNodes[1].value;

// Now do whatever you want with the show title and ratings
}
}
}
}

Bu göreceli olarak basit kodla, bir XML yanıtını, yalnızca düz, biçimlendirilmemiş metin gibi
değil, bir XML gibi işlediniz ve sunucunun yanıtıyla çalışmak için biraz DOM, biraz da basit
JavaScript kullandınız. Daha da önemlisi, virgülle ayrılmış değerler ya da çubukla ayrılmış
ad/değer çiftleri yerine standartlaşmış bir biçimle (XML) çalıştınız. Diğer bir deyişle, XML'i
anlamlı bir yerde kullandınız ve sunucuya istek göndermek gibi anlamsız bir yerde
kullanmaktan kaçındınız.

Sunucuda XML: Kısa bir örnek

Sunucuda XML oluşturma konusuna fazla değinmesem de, çok fazla açıklama yapmadan
küçük bir örnek görebiliriz; böylece, böyle bir durumla nasıl uğraşacağınıza ilişkin kendi
düşüncelerinizi oluşturursunuz. Liste 9'da, zamanuyumsuz bir istemciden gelmiş olabilecek
bir isteğe yanıt olarak XML oluşturan basit bir PHP komut dosyası gösterilmektedir.

Bu, PHP komut dosyasının XML çıkışını manuel olarak zorla oluşturduğu kaba kuvvet
yaklaşımıdır. PHP ve XML yanıtları oluşturabilmenizi sağlayan diğer birçok sunucu tarafı
dillerine ilişkin çeşitli araç takımları ve API'ler bulabilirsiniz. Her durumda bu, size en
azından XML ile istek oluşturan ve yanıtlayan bir sunucu tarafı komut dosyasının neye
benzediğine ilişkin bir fikir verir.

Liste 9. XML döndüren PHP komut dosyası


<?php

// Connect to a MySQL database


$conn = @mysql_connect("mysql.myhost.com", "username", "secret-password");
if (!conn)
die("Error connecting to database: " . mysql_error());

if (!mysql_select_db("television", $conn))
die("Error selecting TV database: " . mysql_error());

// Get ratings for all TV shows in database


$select = 'SELECT title, rating';
$from = ' FROM ratings';
$queryResult = @mysql_query($select . $from);
if (!$queryResult)
die("Error retrieving ratings for TV shows.');

// Let the client know we're sending back XML


header("Content-Type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
echo "<ratings>";

while ($row = mysql_fetch_array($queryResult)) {

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 125/129


$title = $row['title'];
$rating = $row['rating'];

echo "<show>
echo "<title>" . $title . "</title>";
echo "<rating>" . $rating . "</rating>";
echo "</show>";
}

echo "</ratings>";

mysql_close($conn);

?>

Kendi favori sunucu tarafı dilinizi kullanarak benzer bir şekilde XML çıkışı elde edebilmeniz
gerekir. Çok sayıda IBM developerWorks makalesi, tercih edilen sunucu tarafı dili
kullanılarak bir XML belgesinin nasıl oluşturulacağını anlamanıza yardımcı olur (bağlantılar
için bkz. Kaynaklar).

XML'in yorumlanmasına ilişkin diğer seçenekler

XML'i biçimlendirilmemiş metin olarak işlemenin ya da DOM kullanmanın ötesinde, XML


ile çalışmaya ilişkin önemli ve sözünü etmeye değer çok popüler bir seçenek daha vardır. Bu
seçenek, JavaScript Object Notation'ın (JavaScript Nesne Gösterimi) kısaltması olan JSON'dir
ve bu, JavaScript'e eklenen bir serbest metin biçimidir. Bu makalede JSON'yi anlatmak için
yeterli yerim kalmadı, bu nedenle, bu konuya önümüzdeki birkaç ay içinde döneceğim; XML
ve Ajax uygulamalarından söz eder etmez bu konuyla ilgili bir şeyler duyarsınız, dolayısıyla
artık, çalışma arkadaşlarınızın neyle ilgili konuştuklarını bilebilirsiniz.

Genel olarak, JSON ile yapabileceğiniz her şeyi DOM ile de yapabilirsiniz ya da DOM ile
yapabileceğiniz her şeyi JSON ile yapabilirsiniz; bu genellikle tercihle ve belirli bir uygulama
için doğru yaklaşımı seçmeyle ilgilidir. Şimdilik, DOM ile çalışmaya devam edelim ve
sunucunun yanıtını alma bağlamında bunun nasıl kullanılacağını öğrenelim. Birkaç makale
içinde JSON üzerinde oldukça uzun duracağım ve bir sonraki uygulamanızda ikisi arasında
bir seçim yapmak için hazır olacaksınız. Bu nedenle, bu diziyi izlemeye devam edin: Gelecek
makalelerde XML ile ilgili anlatılacak daha çok şey var.

Sonuç

Bu dizinin son makalesinin başlamasından bu yana neredeyse durmaksızın XML ile ilgili
konuşuyorum, ancak henüz XML'in Ajax denklemine katkısının yalnızca yüzeyini biraz
kazıdınız. Gelecek makalemde, XML göndermek (ve XML almak) isteyebileceğiniz belirli
durumlarla ilgili daha ayrıntılı bilgi vereceğim. Özellikle, Web hizmetlerini -- özel olanlar ve
Google gibi API'ler -- Ajax etkileşimi ışığında inceleyeceksiniz.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 126/129


Kısa dönemde en büyük göreviniz, uygulamalarınız için XML'in ne zaman anlamlı olacağı
konusunda gerçekten düşünmek olacaktır. Birçok durumda, uygulamanız iyi çalışıyorsa,
XML baş ağrılarına neden olan teknoloji terimi olmaktan öteye gitmez ve yalnızca
uygulamanızda XML olduğunu söyleyebilmek için XML kullanma isteğinize direnmeniz
gerekir.

Sunucunun size gönderdiği verilerin sınırlı olduğu bir durumda ya da virgül veya çubuklarla
ayrılmış garip bir biçimde, XML gerçekten büyük yararlar sağlayabilir. Sunucu tarafı
bileşenlerinizle çalışarak ya da bu bileşenleri değiştirerek, kesinlikle XML kadar sağlam
olmayan bir özel biçimi kullanmak yerine yanıtları daha standart bir şekilde, XML kullanarak
döndürmelerini sağlayabilirsiniz.

Sonuç olarak, Ajax'la ilgili teknolojiler hakkında ne kadar çok şey öğrenirseniz, kararlarınız
konusunda o kadar dikkatli olmanız gerektiğini unutmayın. Bu Web 2.0 uygulamalarını
yazmak eğlencelidir (ve gelecek makalelerde kullanıcı arabirimine dönecek ve
yapabileceğiniz bazı güzel şeyleri göreceksiniz), çalışan bir Web sayfasına, ancak yalnızca
arkadaşlarınızı etkilemek adına teknoloji eklemediğinizden emin olmak için biraz dikkatli
olmanız gerekir. İyi bir uygulama yazabileceğinizi biliyorum, o zaman gidin ve bunu yapın.
İşinizi bitirdiğinizde, buraya gelip gelecek ayın makalesini okuyun ve daha çok XML öğrenin.

Kaynaklar

Bilgi Edinme

• Ajax'ta Uzmanlaşma: Bu dizinin önceki makalelerini okuyun.

• developerWorks XML bölgesi: Çeşitli teknik makaleler ve ipuçları, senaryolar,


standartlar ve IBM Redbook yayınları için developerWorks XML Zone sitesine bakın.

• developerWorks Web Geliştirme bölgesi: Web 2.0, Ajax, wikis, PHP, mashup'lar ve
diğer Web projeleriyle ilgili kaynaklar bulun.

• developerWorks Açık kaynak bölgesi: Açık kaynak geliştirme ve uygulamasına ilişkin


kaynakları keşfedin.

• Cache in with JSON (Bakul L. Patel, developerWorks, Ekim 2006): İstemci


tarafındaki doğrulama meta verilerini önbelleğe almayı öğrenin.

• xml.com: Deneyimli bir XML programcısı değilseniz, XML konusunda anlaması en


kolay çevrimiçi kaynaklardan biriyle başlayın.

• "Write XML documents with StAX" (Berthold Daum, developerWorks, Aralık 2003):
Düşük düzeyli, imleç tabanlı StAX API'sini verimli bir şekilde kullanarak XML
belgeleri oluşturmaya ilişkin tek bir yöntemle ilgili bu kısa ipucunu okuyun.

• "Servlets and XML: Made for each other" (Doug Tidwell, developerWorks, Mayıs
2000): Bu makalede, Java sunucu uygulamalarının XML ile nasıl çalıştığınız ve
sunucu tarafında nasıl XML oluşturduklarını öğrenin.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 127/129


• "Using Python modules xml2sql and dtd2sql" (David Mertz, developerWorks, Haziran
2001): Python'dan XML ile ilgili daha popüler modüllerin birkaçına ilişkin bu örnekte
bir veritabanı yaratmak ve doldurmak için SQL deyimleri oluşturun.

• "Build dynamic Java applications" (Philip McCarthy, developerWorks, Eylül 2005):


Java bakış açısını kullanarak sunucu tarafından Ajax'a bakın.

• "Java object serialization for Ajax," Philip McCarthy (developerWorks, Ekim 2005):
Ağ üzerinden nesne gönderme ve Ajax ile etkileşimde bulunma konularını Java bakış
açısıyla inceler.

• "Call SOAP Web services with Ajax" (James Snell, developerWorks, Ekim 2005):
Ajax'ın var olan SOAP tabanlı Web hizmetleriyle bütünleştirilmesine ilişkin bu ileri
düzey makaleyi inceleyin; Ajax tasarım şablonunu kullanarak Web tarayıcısı tabanlı
SOAP hizmetleri istemcisini nasıl uygulayacağınızı gösterir.

• World Wide Web Consortium'daki DOM Ana Sayfası: DOM ile ilgili her şeyin
başlangıç noktasını ziyaret edin.

• DOM Level 3 Core Specification (DOM Düzey 3 Çekirdek Belirtimi): Çeşitli


dillerden Belge Nesne Modeli'nin kullanabileceği tipleri ve özellikleri kullanarak
çekirdek DOM'yi tanımlayın.

• ECMAScript language bindings for DOM (DOM için ECMAScript dil


ilişkilendirmeleri): Bir JavaScript programcısıysanız ve kodunuz için DOM kullanmak
istiyorsanız, Düzey 3 Belge Nesne Modeli Çekirdeği tanımlarına ilişkin bu ek ilginizi
çekecektir.

• "Ajax: A new approach to Web applications" (Jesse James Garrett , Adaptive Path,
Şubat 2005): Ajax moniker teriminin ilk kez kullanıldığı bu makaleyi okuyun -- tüm
Ajax geliştiricileri bu makaleyi okumalıdır.

• developerWorks teknik etkinlikleri ve Web yayınları: Teknik geliştiricilere yönelik bu


yazılım brifinglerini takip edin.

Ürün ve teknoloji edinme

• Head Rush Ajax (Brett McLaughlin, O'Reilly Media, 2006): Bu makaledeki fikirleri
Head First yöntemiyle öğrenin.

• Java and XML, Second Edition (Brett McLaughlin, O'Reilly Media, Inc., 2001):
Yazarın XHTML ve XML dönüşümleriyle ilgili görüşlerini okuyun.

• JavaScript: The Definitive Guide (David Flanagan, O'Reilly Media, Inc., 2001):
JavaScript ve dinamik Web sayfalarıyla çalışmaya ilişkin kapsamlı yönergeleri
inceleyin. Yayınlanacak olan yeni basımda Ajax ile ilgili iki yeni bölüm vardır.

• Head First HTML with CSS & XHTML (Elizabeth and Eric Freeman, O'Reilly Media,
Inc., 2005): Standartlaşmış HTML ve XHTML ve CSS'yi HTML'ye uygulamayla
ilgili daha fazla bilgi öğrenin.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 128/129


• IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki
geliştirme projenizi oluşturun.

Tartışma

• developerWorks Web günlükleri: DeveloperWorks topluluğuna katılın.

• Ajax forum on developerWorks: AJAX'ı yeni öğrenen ya da etkin olarak kullanan


Web geliştiricilerinden oluşan bu forumda yeni bilgiler öğrenin, düşüncelerinizi
tartışın, bildiklerinizi paylaşın.

Ajax Üzerine Ayrıntılı Bir İnceleme.doc 129/129

You might also like