Merhaba arkadaşlar,
ASP.NET projeleri geliştirenlerimiz çok iyi bilirler, en büyük sorunlarımızdan birisi postback işlemleri, bu işlemleri yönetmek ve mümkün olduğunca server'a daha az veri göndermek ve daha az veri almaya çalışmaktır. Bu cümleden yola çıkarak sizinle bu konuda biraz daha derine inmek istiyorum. Konumuzun içersine şu şekilde adım atalım; Postback üzerine neden bu kadar fazla eğiliyoruz, neden eğilmemiz gerekir?
Şekilde, sunucuya istemci tarafından yapılan tek bir talep sonrasında meydana gelen döngü basit haliyle anlatılmak istenmiştir. Burada görüldüğü gibi istemciden sunucuya giden her talep, sunucu tarafından değerlendirilerek sayfa verisi yeniden oluşturulmakta, oluşturulan sayfa verisinin tamamı sunucudan istemciye gönderilmektedir. Burada bir noktaya dikkatinizi çekmek istiyorum. İstemci bir talep bildirmek için sayfa verisinin tamamını server'a göndermek zorundadır. Sunucu da (server) talepi değerlendirerek, sayfanın yaşam döngüsünü (page life cycle) çalıştırmakta, istenen veriyi oluşturmakta, talepe uygun sayfayı (html çıktısını) yeniden yaratmakta ve client'a (istemci) göndermektedir.
Bu döngüyü sizlerle paylaşmak için yazarken bile parmaklarım yoruldu. Aktif kullanıcı sayısı ve işlenmesi gereken verisi fazla olan uygulamalarda sunucunun halini varın siz düşünün.
İsterseniz olaya şöyle bir senaryo üzerinden devam edelim; ASP.NET uygulamanızın bir kısmında bir kişiye ait kimlik bilgilerini sorgulamanız gerekiyor. Ve sorgu sonucunda kişinin doğum tarihini, anne adını ve baba adını almalısınız. Ne kadar basit değil mi? Ne kadar basit demeden önce isterseniz yukarıda ki şekli yeniden inceleyin.
Eğer sorgu sonucunu sunmak için talep yapacağımız sayfa (yönleneceğimiz) sorgu kriterlerini belirlediğimiz sayfadan farklı bir sayfa ise, bu talep içerisinde ki sorgu kriterlerini QueryString yada Session nesneleri yardımı ile ilgili sayfaya ulaştırırız (farklı durumlarda formu tamamen sunum sayfasına post edebilir yada asp.net cross page postback'ten yararlanabiliriz). Eğer sorgu kriterlerini alacağımız sayfa ile sorgu sonucunu (resultset) göstereceğimiz sayfa aynı ise ek bir çaba harcamamıza gerek olmaz. Lakin postback sonrasında talepi değerlendireceğimizden dolayı, sorgu kriterlerini kullanıcıdan almak için kullandığımız kontrollerin değerlerinden zaten haberdar oluruz. Bu bahsettiğim veri taşıma yöntemlerinden bazıları ise sayfanızın html kodunun şişmesine, bir başla deyişle byte değerinin artmasına sebep olacaktır.
Olayın ne derece ciddi boyutlarda olduğuna daha iyi dikkat çekebilmek için şöyle bir örnek vermek isterim; Sorgu kriterlerimizi QueryString vasıtasıyla gönderdiğimizi ve [url + QueryString] bilgilerimizin toplam 120 karakterden oluştuğunu düşünelim. Bu da toplam 120byte veri göndereceğimiz anlamına gelir. Üzerinde sadece bir iki resim olan bir html sayfası bile binlerce byte'tan oluşur. Binlerce byte değeri gönderip almak mı daha kolaydır yoksa 120byte veriyi mi göndermek daha kolaydır. Dikkatinizi çekmiştir, geriye ne kadar veri alacağımızdan bahsetmedim. Çünkü bu server'dan ne istediğimize göre değişecektir. Ancak alacağımız veriyi tahmin etmek için şöyle bir kaba hesap yapabiliriz;
[Sunucu Cevabı Veri Miktarı] = [Alacağımız Veri Miktarı] + [Sayfayı Oluşturan Html İçeriğin Veri Miktarı]
Veri talep yöntemimiz yukarıda bahsettiğim yöntemlerin hangisi olursa olsun, tüm sayfa verisini göndermek yerine sadece talep edeceğimiz veriye ait bilgileri yollamanın ve sunucudan sadece talep ettiğimiz bilgileri almanın bir yolunu bulmalıyız. Eğer bunun bir yolunu bulabilirsek hem uygulamalarımızı son derece hızlandırmış olacağız hem de network trafiğini azalttığımız için bulunduğumuz network üzerinde çalışan diğer uygulamalarda rahatlamış (hızlanmış) olacaklar.
Peki bunu nasıl yapabiliriz? Cevabı sizlerde çok rahat tahmin etmişsinizdir, AJAX kullanabiliriz. Benim bu yazımda sizlerle paylaşmak istediğim teknik hatta teknik demek yanlış olabilir, nesne; XMLHttp nesnesi. Bu nesne yardımı ile sayfalarımızın istediğimiz yerinden HTTP talepleri gönderebiliriz (get,post,head,put,delete). Aslında bu nesnemiz yeni bir nesne değil. Uzun süredir var olan bir nesne. Bu nesnenin geçmişi IE 5.0'a kadar gitmektedir. Microsoft IE 5.0 ile birlikte XMLHttp adında ki ActiveX kütüphanesini tanıtmış ve zaman içerisinde,
- Microsoft.XMLHttp
- MSXML2.XMLHttp
- MSXML2.XMLHttp.3.0
- MSXML2.XMLHttp.4.0
- MSXML2.XMLHttp.5.0
- MSXML2.XMLHttp.6.0
olarak yayınlanmış versiyonları çıkmıştır, sonuncusu ise MSXML2.XMLHttp.6.0'dır. Tüm browser'ların XMLHttp nesnesine destek vermeyeceğini dikkate alarak geliştirme yapmalıyız. Bu yüzden Microsoft ilk önce MSXML2.XMLHttp.6.0 nesnesini yaratmayı denememizi eğer başarısız olursak geriye dönük destek için MSXML2.XMLHttp.3.0'ı yaratmamızı tavsiye ediyor. Bunu anlamı şudur, bu nesneyi kullanmaya başlamadan önce tarayıcının ActiveXObject'i destekleyip desteklemediğine bakmamız eğer destekliyorsa desteklediği en yüksek XMLHttp sürümünü yaratmamız gerekmektedir. Bunun için şu şekilde bir javascript fonksiyonu yazabiliriz;
function createXHR()
{
// Tarayıcımızın ActiveXObject desteği olup olmadığını kontrol ediyoruz.
if(typeof ActiveXObject != "undefined")
{
// Nesne versiyonları bir dizi içersine alınıyor.
var versiyonlar = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0"];
try
{
// Döngü ile her versiyon en son sürümden başlamak
// üzere oluşturulmaya çalışılıyor.
for(var i=0;i<versiyonlar.length;i++)
{
var XHR = new ActiveXObject(versiyonlar[i]);
return XHR;
}
}
catch
{
throw new Error("MSXML nesnesi desteklenmiyor.");
}
}
} |
Bu function ile bir XMLHttp nesnesi oluşturulmak istenmiştir. Bunun için ilk önce tarayıcının ActiveXObject desteği olup olmadığı (kapalı olması gibi - IE 6.0 ve öncesinde) kontrol edilmiş, eğer tarayıcı ActiveXObject desteği sunuyorsa, XMLHttp nesnesine olan destek kontrol edilerek, destek verilen en son sürüm oluşturulmuştur. Eğer ihtiyacımız olan destek browser tarafından sağlanamıyorsa bir hata fırlatılmıştır.
createXHR() fonksiyonu ile ActiveX nesnemizi oluşturduğumuza göre artık onu kullanabiliriz. XMLHttp nesnesinin "open" adında bir metodu vardır. Bu metod yardımı ile hangi HTTP metodu ile nereye talepte bulunacağımızı belirtiriz. Bir başka deyişle işlemi nasıl ve nerede yapacağımızı belirtiriz. Open metodu 5 adet parametre alır.
open(sMethod, sUrl, bAsync, sUser, sPassword)
Bu parametrelerden son 3 tanesi opsiyoneldir ancak bizim örneklerimizde "bAsync" parametresinin büyük önemi vardır. Bu parametrelerin görevleri sırası ile;
sMethod : |
String değer alır ve bağlantı açmak için kullanılan HTTP metodunun adıdır. GET,POST,HEAD,PUT,DELETE parametrelerini alır ve büyük-küçük harf duyarlılığı yoktur. |
sUrl : |
String değer alır ve talepte bulunulacak olan sayfanın yada servisin adresidir. |
bAsync: |
Talebin yanıtının asenkron olarak alınıp alınmayacağını belirtir. Eğer asenkron alınacak ise true değilse false verilir. |
sUser: |
Authentication gerektiren yerlerde kullanılır. Null ("") değer atanabileceği gibi hiç değer atamadan da geçilebilir. |
sPassword: |
Authentication gerektiren yerlerde kullanılır. Null ("") değer atanabileceği gibi hiç değer atamadan da geçilebilir. |
İlerlemeden önce sAsync parametresine değinmek istiyorum. Eğer bu parametreye "true" değeri verirsek, kodumuz başlattığımız işlemin sonucunu beklemeden geri kalan işlemleri yapmak için çalışmaya devam edecektir. Ancak sAsync parametresine "false" atarsak, kodumuz başlattığımız HTTP talebinin sonucunu bekleyecek ve sonuç geldikten sonra çalışmaya devam edecektir. Bu parametrenin çalışma mantığını anlamak, kod performansı ve oluşabilecek hataların önüne geçebilmek açısından çok önemlidir. Eğer bir işleme başlamadan önce XMLHttp nesnesi ile yaptığınız talepten dönecek olan sonuca itiyacınız varsa sAsync parametresinin değerini "false" olarak ayarlamalısınız. Aksi halde büyük ihtimalle bir hata alırsınız. Eğer yapacağınız işlem için XMLHttp nesnesi ile yaptığınız talep sonucunda dönecek değere/değerlere ihtiyacınız yoksa sAsync parametresine "true" değeri atamalısınız. Aksi halde kodunuz boşu boşuna talep sonucunu bekleyecek ve zaman kaybedecektir.
Bu nesne ile yaptığımız taleplerin durumlarını takip edebilmekte bizim için hayati öneme sahiptir. Acaba talep sunucuya ulaştı mı, sunucu talebin hangi evresinde, talepte bir sorun oluştu mu gibi bilgiler bizim için çok önemlidir. Allahtan ki Microsoft bu durumu düşünürek bir kaç özellik ve event eklemiş nesneye. Ele alacağımız eventin adı onreadystatechange dir. Bu event sayesinde yapmış olduğumuz talebin ne durumda olduğu hakkında fikir sahibi oluruz. Bunu da olay (event) içerisinde XMLHttp nesnesine ait readyState property'sinden yararlanarak yaparız. readyState özelliğinin 5 adet değeri vardır;
0 (Başlatılmamış) : |
Nesne create edilmiş ancak başlatılmamış yani open metodu çağrılmamış. |
1 (Başlatılmış) : |
Nesne yaratılmış yani open metodu çağrılmış ancak send metodu çağrılmamış. |
2 (Gönderilmiş) : |
Send metodu çağrılmış, resposeText ve responseBody özellikleri kullanılabilir değil. |
3 (Veri Alınıyor) : |
Bazı datalar alınıyor, resposeText ve responseBody özellikleri kullanılabilir değil. |
4 (Yüklendi) : |
Tüm veriler alındı, resposeText ve responseBody özellikleri kullanılabilir. |
readyState özellğinin aldığı değerleri anlatırken bilmediğimiz 3 farklı kelime çıktı karşımıza. send metodu responseText ve responseBody özellikleri. responseText ve responseBody özellikleri, talebimiz sonucunda dönen değeri string olarak alırlar. Ancak aralarında bir fark vardır. responseText bu sonucu string olarak verirken, responseBody byte array olarak verir.
Send metodu ise konumuzun ana metodlarından biridir. Open metodu ile belirlediğimizi sayfaya yada servise (web service) talebimizi yollamamızı sağlar. Bu andan itibaren bize sadece readyState'in değerlerini takip ederek talebimizin sonucunu beklemek kalır.
Send metodu string türünden tek bir parametre alır ve bu parametre opsiyoneldir ancak parametreye hiç bir değer atamadan metod kullanılamaz. En azından bir "null" değer ataması yapmak gerekir. Peki bu parametre ne işe yarar? Bu parematre ile get ve post isteklerimiz için gerekli olacak olan parametreleri sunucuya gönderebiliriz. Örnek uygulamımızı incelerken ne demek istediğimi daha iyi anlayacaksınız.
Unutmadan status özelliğinden de bahsetmek istiyorum. Bu özellik talebimizin HTTP durum kodunu verir. Bu durum kodunu, talebimizin ne durumda olduğunu anlamak için readyState özelliğinin değerini kontrol ettikten sonra, talebimizde bir sorun olup olmadığını anlamak için kullanacağız. HTTP status kodlarının listesine ve anlamlarına buradan ulaşabilirsiniz.
Artık bir örnek üzerinden devam edelim ve bir HTTP get metodunu ele almaya çalışalım. Durumu örneklendirmek için yazının önceki satırlarında vermiş olduğum kimlik bilgisi sorgulama senaryosu gayet uygun ancak örnek kodları incelemek için indirdiğinizde sisteminizde hali hazırda bulunmayan bir database ile de uğraşmanız gerekecek. Bu yüzden AdvantureWorks veritabanı üzerinden çalışarak bir örnek geliştirmek daha uygun olacaktır. Şimdi ilk senaryomuza yakın yeni bir senaryo oluşturalım. Mesela personelimizin adını ve soyadını parametre olarak vererek, personele ait mail adresine ulaşmamız gereksin. Amacımız personelin mail bilgilesini talep ederken ve alırken ASP.NET postback'inden kaçınmak ve uygulamamıza hız katarak kullanıcı deneyimini arttırmak. Çok süslü bir cümle oldu. Bakalım bunun altından kalkabilecekmiyiz.
Örneğimiz için hazırlamış olduğum sorgu parametre ekranı şu şekilde;
Html kodları ise şöyle;
<table border="0px" style="width:100%;">
<tr>
<td style="width: 10%;">
Adı :
</td>
<td>
<input id="txtAdi" name="txtAdi" type="text" />
</td>
</tr>
<tr>
<td style="width: 10%;">
Soyadı :
</td>
<td>
<input id="txtSoyadi" name="txtSoyadi" type="text" />
</td>
</tr>
<tr>
<td colspan="2">
<input id="btnSorgula" type="button"value="Mail Adresini Getir" onclick="startRequest()" />
</td>
</tr>
<tr>
<td colspan="2">
<div id="divSonuc" ></div>
</td>
</tr>
</table>
|
Gördüğünüz gibi tamamen amacımıza yönelik bir tasarım :) Ekranda basitçe, ad ve soyad bilgilerini almak için kullanacağımız 2 adet text kontrolü (isterseniz asp.net textBox kontorolünü de kullanabilirsiniz) ve mail adresini öğrenmek için olayları başlatacağımız bir buton mevcut. Butonun "onclick" eventine dikkat edin. Bir metoda ayarlanmış durumda. İşte dananın kuyruğunun koptuğu yer burası. Gelin bu dananın kuyruğunun nasıl koptuğuna birlikte bakalım.
<script language="javascript" type="text/javascript">
function startRequest() {
// XMLHttp nesnesi yaratmak için alternatif yol.
// var XHR = new XMLHttpRequest;
var XHR = createXHR();
var divStatus = document.getElementById("divSonuc");
var parametreler = encodeURIComponent("ad") + "=" + encodeURIComponent(document.getElementById("txtAdi").value) + "&" +
encodeURIComponent("soyad") + "=" + encodeURIComponent(document.getElementById("txtSoyadi").value)
XHR.open("get", "DataPage.aspx?" + parametreler, true);
XHR.onreadystatechange = function() {
if (XHR.readyState == 4 && (XHR.status == 200 || XHR.status == 304)) {
divStatus.innerHTML = "Eposta Adresi: " + XHR.responseText;
}
else {
divStatus.innerHTML = "Bir hata meydana geldi: " + XHR.statusText;
}
}
XHR.send(null);
}
function createXHR()
{
// Tarayıcımızın ActiveXObject desteği olup olmadığını kontrol ediyoruz.
if(typeof ActiveXObject != "undefined")
{
// Nesne versiyonları bir dizi içersine alınıyor.
var versiyonlar = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0"];
try
{
// Döngü ile her versiyon en son sürümden başlamak
// üzere oluşturulmaya çalışılıyor.
for(var i=0;i<versiyonlar.length;i++)
{
var XHR = new ActiveXObject(versiyonlar[i]);
return XHR;
}
}
catch(err)
{
throw new Error("MSXML nesnesi desteklenmiyor.");
}
}
}
</script>
|
Olayı ele almaya bence startRequest() metodu ile başlayalım. createXHR() metodunu zaten önce ki satırlarda incelemiştik. Tekrar tekrar aynı şeylerden bahsederek can sıkmaya ve konsantrasyon dağıtmaya gerek yok. startRequest() metoduna dönecek olursak, bu metod ne yapar? Bu metod HTTP get talebimizi başlattığımız ve sonuçlarını aldığımız yerdir. Bold (kalın) olarak yazılmış yerlere özellikle dikkatinizi çekmek istiyorum. İlk önce createXHR() metodu ile HTTP isteklerimiz başlatabilmemiz için gerekli olan ActiveX nesnemizi create ediyoruz. Burada biraz duralım. ActiveX objemizi create ettiğimiz yerin üzerinde önemli bir yorum var. Burada XmlHttpRequest nesnesini görüyoruz. Aslında bu bir API'dir. Server ve client arasında HTTP metod iletişimini sağlayan bir API. Ancak kullanımı çok hoş olmasına karşın ufak bir kusuru vardır; GET isteklerinde sunucunun istemciye olan yanıtı boş bir text ise, IE 7.0 ve IE 8.0 sunucuya yeni bir istek daha gönderir. bu böyle devam edip gidebilir. Bu bir bug'dır. Bundan sakınmak için server-side kodlarınızda istemciye gönderecek olduğunuz yanıtı hazırlarken her zaman dolu (en azından bir boşluk karakteri) bir text gönderdiğinizden emin olmalısınız. Diğer IE surumlerinde, diğer browser'larda ve POST isteklerinde bu sorun yoktur.
Kodu incelemeye devam edecek olursak, XMLHttp nesnemizi yarattıktan sonra open metodu ile ne yapacağımızı set ediyoruz. Biz "DataPage.aspx" sayfasına bir GET talebinde bulunacağımızı ve talebimiz sonucu oluşan yanıtı asenkron olarak almak istediğimizi belirttik. Tabii bu bir HTTP get isteği olduğu için parametrelerimizi QueryString ile sunucuya göndereceğiz. Bunun için open metodundan önce parametreler isimli değişken ile QueryString verilerimizi oluşturduk. Gelelim asenkron olayına. Bu örnekte direk olarak sunucuya istek başlattığımız ve gelen sonuçlar üzerinde işlem yada işlemler yapmadığımız için bAsync parametresinin "true" yada "false" olmasının bir önemi yok. Ancak talebimizi farklı bir metod içersinden başlatmış olsaydık ve dönecek olan değer üzerinde işlem yapamamız gerekseydi, o zaman burada kullanacağınız "true" ve "false" atamasının çok büyük önemi olacaktı.
Open metodunun arkasından XHR nesnemizin onreadystatechange eventine bir fonksiyon bağlıyoruz. XHR nesnemizin readyState değeri her değiştiğinde onreadystatechange olayı tetiklenecektir. Bu yüzden bu olay içersinde sunucudan gelen yanıtı almaya çalışıyoruz. Gördüğünüz gibi onreadystatechange eventi içerisinde XHR nesnemize ait readyState ve status özelliklerinin değerlerini kontrol ediyoruz ve bazı değerler sağlandığında sunucudan gelen yanıt üzerinde işlemler yapıyoruz. Burada readyState özelliğini başlattığımız talebin ne durumda olduğunu, status özelliğini ise sunucudan dönen yanıtın header değerini alarak client talebini işleme esnasında server'da bir sorun oluşup oluşmadığını anlamak için kullanıyoruz. Biz örneğimizde ne yaptık; Eğer talebimizin yüklenmesi tamamlandı ise (readyState özelliğinden dönen değer ile anladık) ve sunucu bize 200 yada 304 durum kodunu gönderdi ise (status özelliği ile alıyoruz) talebimizin tamamlandığını ve sunucudan sonucu sorunsuzca alabileceğimizi anladık, hemen arkasından da divStatus isimli div'in içerisine sunucudan gelen cevabı yazdırdık. Sunucudan gelen cevabı responseText özelliği ile aldık. responseText özelliği adından anlaşılabileceği gibi yanıta ait text'e ulaşmamızı sağlayan özelliktir.s
Yukarıda anlattıklarımın hepsi istemci tarafında yapmamız gereken işlemlerdi. Peki sunucu tarafında istemciden yapılan HTTP get talebini nasıl ele alacağız? Aslında XHR nesnemize ait open metodu bize gayet sağlam fikirler veriyor. Önce ki satırlarda open metodu ile ne yaptığımızı açıklarken ne demiştim; DataPage.aspx sayfasına get talebinde bulunacağımızdan bahsetmiştim. Öyleyse HTTP get talebini DataPage.aspx sayfasının içerisinde, load eventinde, QueryString ile gelen değerler doğrultusunda ele alacağız. Ancak burada belirtmem gereken önemli bir nokta var; Talebe verilen yanıt sayfanın akışına yazdırılır. ASP.NET page'inden bahsedecek olursak, Response.Write metodu kullanılarak talep sonrası oluşturduğumuz yanıtı akışa yazdırırız. Ancak akış içerisinde herhangi bir html yada benzer bilgi olmamalıdır. Başka bir deyişle, yanıtımızın türü "text/Plain" türünde olmalıdır. Bu yüzden asp.net sayfamızın en üstünde bulunan "Page" direktifi haricinde ki tüm satırları siler (html satırlardan bahsediyorum) kod tarafında ise header'ımızı "text/Plain" olarak ayarlarız. Page'imize ait source şu şekilde olacaktır;
Page'imizin soruce'unda ne yapmamız gerektiğini inceledikten sonra code-behind'a geçerek gelin bir de load event'inde ne yaptığımıza bakalım.
protected void Page_Load(object sender, EventArgs e)
{
// Sayfa tam bir asp.net sayfası değil hatta html bile değil.Zaten bizden de dönen değerlerin "text/Plain" olması istenir.
// Bu yüzden HTTP header bilgimizi bu şekilde ayarlıyoruz.
Response.ContentType = "text/Plain";
SqlConnection connect = null;
SqlCommand command = null;
try
{
string ad = Page.Request.QueryString["ad"].ToString();
string soyad = Page.Request.QueryString["soyad"].ToString();
connect = new SqlConnection("server=TOLGA-PC;database=AdventureWorks;integrated security=SSPI;");
command = new SqlCommand("SELECT EmailAddress FROM Person.Contact WHERE FirstName=@adi AND LastName=@soyadi", connect);
command.Parameters.AddWithValue("@adi",ad);
command.Parameters.AddWithValue("@soyadi",soyad);
connect.Open();
Object email = command.ExecuteScalar();
connect.Close();
if (email == null || email == DBNull.Value)
{
Page.Response.Write("Personele ait mail adresi bulunamadı.");
}
else
{
Page.Response.Write((string)email);
}
}
catch(Exception ex)
{
Page.Response.Write("Sorgu sırasında bir hata meydana geldi. Hata: " + ex.Message);
}
finally
{
if(connect.State != System.Data.ConnectionState.Closed) connect.Close();
if (connect != null) connect.Dispose();
if (command != null) command.Dispose();
connect = null;
command = null;
}
}
}
|
Kod içerisinde ki kalın ile yazılmış olan yerlere dikkatinizi çekmek istiyorum. Kalın olarak formatlanmış yerlerde yapılanlar çok önemli. Kodu kısaca açıklamak gerekirse; İlk önce sayfamızın content'ini "text/Plain" olarak ayarladık. Arkasından, istemci tarafında talebimizi başlatmak için kullanmış olduğumuz open metodu ile gönderilen QueryString değerlerini okuduk ve database'den ilgili kişiye ait mail adresini alarak sayfanın akışına yazdırdık. Tüm yapılan işte bu kadar.
Tüm bu anlatılanları daha iyi anlayabilmek için bahsi geçen örnek uygulamayı bilgisayarınıza indirerek incelemenizi öneririm. Bu şekilde okuduklarınızdan maksimum katkı sağlayabilirsiniz. Bu gün HTTP GET talepleri ile ajax tekniğini nasıl kullanabileceğimizi incelemeye çalıştık. İlerleyen günlerde HTTP POST taleplerini de incelemeye çalışacağız. Şimdilik hoşçakalın.
Selamlar.
Tolga AYKURT
tolga_aykurt[et]hotmail.com