創(chuàng)建時(shí)間選擇 既然我們已經(jīng)知道如何創(chuàng)建XMLHttpRequest,那么還需要考慮何時(shí)來創(chuàng)建。在XMLHttpRequest對(duì)象創(chuàng)建的示例中,盡管我們事先沒有發(fā)送任何請(qǐng)求,但仍可以創(chuàng)建成功,也就是說,我們可以在需要的時(shí)候創(chuàng)建對(duì)象。 當(dāng)你需要?jiǎng)?chuàng)建XMLHttpRequest對(duì)象時(shí),面對(duì)的一個(gè)問題是沒有信息顯示客戶能否創(chuàng)建該對(duì)象。假設(shè)一個(gè)用戶訪問你的網(wǎng)站并且無法創(chuàng)建XMLHttpRequest對(duì)象,如果能從第一時(shí)間就知道AJAX沒有被選擇,你就可以更早地提供給他們。 對(duì)于一個(gè)開始與你的Web應(yīng)用程序進(jìn)行互動(dòng)的用戶,當(dāng)他們被告知只有點(diǎn)擊提交按鈕才能使用該程序時(shí),這決不是一件好事,讓他們填寫表單也是完全在浪費(fèi)時(shí)間。 然而如果在頁面打開階段就能試圖創(chuàng)建XMLHttpRequest,在用戶開始互動(dòng)之前就提供選擇,比如轉(zhuǎn)入非AJAX頁面。 設(shè)置請(qǐng)求 眼下,有一個(gè)頁面在加載后就需要?jiǎng)?chuàng)建XMLHttpRequest對(duì)象,我們現(xiàn)在有意做出請(qǐng)求。 為此,我們必須向打開方式傳遞至少兩個(gè)參數(shù),其中大部分參數(shù)的含義都可以直接理解。 xmlhttp.open(Method, Url [, Async] [, User] [, Password]) 參數(shù)Method定義了請(qǐng)求方法;可選擇的有"POST", "GET" 或 "HEAD"。首先,我們只準(zhǔn)備使用GET。 Url是要請(qǐng)求頁面的url字符串。我們無法訪問和向舊頁面做出請(qǐng)求,有一個(gè)阻止我們?cè)L問與所創(chuàng)建請(qǐng)求頁面不在同一范圍內(nèi)的其他頁面的壁壘。 Async也是AJAX建立的基礎(chǔ)。盡管前者在API中是一個(gè)備選參數(shù),但在這里該參數(shù)是強(qiáng)制性選項(xiàng),必須設(shè)置為true,如果設(shè)為false,該項(xiàng)將保持直到獲得響應(yīng)。該參數(shù)的默認(rèn)值是True,所以你可以選擇不設(shè)置,但是考慮到可讀性以及可維護(hù)性,強(qiáng)烈推薦設(shè)置該值。 用戶名和密碼用于驗(yàn)證身份時(shí)選擇 一旦我們?cè)O(shè)置Async為true,我們需要定義一種命令方式,用于回應(yīng)請(qǐng)求狀態(tài)改變-可以通過設(shè)置XMLHttpRequest對(duì)象中的onreadystatechange屬性完成。 xmlhttp.onreadystatechange = myReturnMethod; xmlhttp.send(null); 最后需要做的是把請(qǐng)求發(fā)送出去,先說最簡單的,我們只發(fā)送不含任何附加數(shù)據(jù)的請(qǐng)求: 在一個(gè)簡單的示例中綜合了上述所有內(nèi)容: xmlhttp.open("GET", "/some_dir/myfile.html", true); xmlhttp.onreadystatechange = myReturnMethod; xmlhttp.send(null); 上述三行代碼就是我們進(jìn)入AJAX世界所需要的全部內(nèi)容,沒有包含任何復(fù)雜的概念或曲折的邏輯 對(duì)象狀態(tài) 上文中提到過,我們需要定義一種命令方式,用于回應(yīng)請(qǐng)求狀態(tài)改變,這可以通過設(shè)置onreadystatechange屬性完成,請(qǐng)注意我所說的是“狀態(tài)改變”,并不是“完成”-因?yàn)檫@兩者之間是完全不同的。結(jié)合我們剛才所學(xué)的知識(shí),最好通過例子來說明。寫入如下代碼: <script> var xmlhttp = false; try { xmlhttp = new XMLHttpRequest(); } catch (trymicrosoft) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (othermicrosoft) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (failed) { xmlhttp = false; } } } function goAJAX() { alert("InitialReadyState is:"+xmlhttp.readyState); xmlhttp.onreadystatechange = myReturnMethod; xmlhttp.open("GET", "another_file.html", true); xmlhttp.send(null); } function myReturnMethod() { alert("NewReadyState is:"+xmlhttp.readyState); } </script> <button onclick="javascript:goAJAX()">Let‘s try it!</button> 在被請(qǐng)求的文件中,我們可以填補(bǔ)任何我們想要的內(nèi)容,只要可以建立,我們就不打算使用其中的內(nèi)容。 點(diǎn)提交按鈕前,我們還應(yīng)該注意,對(duì)象狀態(tài)警告出現(xiàn)多次,最終顯示的對(duì)象狀態(tài)值是4。不同的瀏覽器對(duì)此的處理方法不同,Safari精確地從0-4計(jì)數(shù),對(duì)于firefox,1出現(xiàn)兩次,0只在運(yùn)行的第一次出現(xiàn)。值得慶幸的是,我們僅僅對(duì)readyState是4的情況感興趣,但是為了完整性,我們還是看看其他數(shù)字所代表的含義。 0:未初始化-打開命令之前,對(duì)象不包含數(shù)據(jù) 1:對(duì)象正在加載數(shù)據(jù)-發(fā)送請(qǐng)求命令之前 2:加載完畢-請(qǐng)求已經(jīng)被發(fā)出 3:交互-請(qǐng)求正在被處理,可能會(huì)得到一些數(shù)據(jù),但不完全,所以不能安全使用 4:完成-請(qǐng)求已完成,最終數(shù)據(jù)可以安全使用。 這些新信息說明,只有在警告顯示請(qǐng)求完成后,才能改變myReturnMethod。 function myReturnMethod() { if (xmlhttp.readyState==4){ alert("NewReadyState is:"+xmlhttp.readyState); } }
響應(yīng)狀況 采用先前的代碼,我們改變open method中的url參數(shù)到一個(gè)不存在的文件中: xmlhttp.open("GET", "filethatdoesnotexist.html", true); 再次運(yùn)行該代碼,我們看到和先前的代碼執(zhí)行了相同的結(jié)果-為什么會(huì)這樣? 如果這是一個(gè)正常http請(qǐng)求,我們預(yù)計(jì)404錯(cuò)誤會(huì)出現(xiàn)-在AJAX中也具有相同的狀況屬性。該屬性僅可讀,包含HTTP請(qǐng)求狀況代碼,我們這里的文件對(duì)應(yīng)的代碼是404。應(yīng)用于一般http請(qǐng)求的相同狀況代碼仍適用AJAX。(注意:為了正常運(yùn)行,頁面應(yīng)該讀取來自一個(gè)HTTP服務(wù)器的請(qǐng)求,如果從文件系統(tǒng)中讀取,該狀況代碼將始終是未定義的。) 因此,我們需要增加一個(gè)if陳述,用來測試請(qǐng)求是否成功,如果是一個(gè)200的響應(yīng)代碼,將被成功返回。如果不成功,我們必須選擇恰當(dāng)?shù)姆绞絹斫鉀Q錯(cuò)誤。 function myReturnMethod() { if (xmlhttp.readyState==4){ if (xmlhttp.status == 200) { alert("Request successfully completed"); } else if(xmlhttp.status == 404) { alert("Requested file not found"); } else { alert("Error has occurred with status code: "+xmlhttp.status); } } } ResponseText與responseXML 盡管我們已經(jīng)可以成功地完成一個(gè)AJAX請(qǐng)求,但還需要對(duì)返回的數(shù)據(jù)做出處理。通過應(yīng)用responseText 或responseXML屬性,我們有兩種處理的方式。最簡單的方法是直接獲取從服務(wù)器返回的數(shù)據(jù),使用responseText屬性中返回的純文本數(shù)據(jù)。這樣得到的數(shù)據(jù)可以是任何我們想要的形式;簡單的文本響應(yīng),符號(hào)劃界值或一整本字符串名冊(cè)。在我們的返回方法中,我們將在警告中輸出responseText,這將輸出我們請(qǐng)求的整個(gè)文件內(nèi)容。 在這個(gè)階段,如果你還沒有向我們發(fā)出請(qǐng)求的文件- another_file.html中輸入任何內(nèi)容,你應(yīng)該做了。 function myReturnMethod() { if (xmlhttp.readyState==4){ if (xmlhttp.status == 200) { alert(xmlhttp.responseText); } else if(xmlhttp.status == 404) { alert("Requested file not found"); } else { alert("Error has occurred with status code: "+xmlhttp.status); } } } 另一個(gè)可供選擇的找回返回?cái)?shù)據(jù)的方法是使用responseXML屬性,其將以XML文檔對(duì)象的形式返回?cái)?shù)據(jù),利用Javascript的DOM功能可以對(duì)其研究。為了看到這一動(dòng)作的結(jié)果,我們需要返回一個(gè)恰當(dāng)?shù)腦ML格式文檔;我們就創(chuàng)建一個(gè)新文件來請(qǐng)求(xmlresult.html), 并寫入以下代碼: <?xml version="1.0" encoding="UTF-8"?> <root> XML Formatted Result </root> 然后我們需要將打開命令改為: xmlhttp.open("GET", "xmlresult.html", true); 在我們的返回方法中所作的最大改變是,我們需要在那里替換警告(xmlhttp.responseText),代碼如下: xmldoc = xmlhttp.responseXML; rootnode = xmldoc.getElementsByTagName(‘root‘).item(0); alert(rootnode.firstChild.data); 瞧,我們正在利用DOM來返回?cái)?shù)據(jù)。 通過結(jié)合我們所了解到的現(xiàn)有的javascript功能,該數(shù)據(jù)可被用于應(yīng)付一個(gè)頁面的內(nèi)容。例如: document.getElementById(‘resultdiv‘).innerHTML = xmlhttp.responseText; 何時(shí)使用AJAX 既然已經(jīng)知道如何創(chuàng)建一個(gè)請(qǐng)求以及返回結(jié)果,那么還有一個(gè)問題是何時(shí)該使用AJAX呢? 對(duì)于一項(xiàng)新技術(shù)自然會(huì)有兩方面的極端意見,一些網(wǎng)絡(luò)開發(fā)者認(rèn)為,如果沒有AJAX,生活將變得更簡單;另一些人則巴不得見到由AJAX構(gòu)建的整個(gè)網(wǎng)站。通常這種情況下,真理往往介于這兩種觀點(diǎn)之間。當(dāng)決定在你的網(wǎng)站上使用AJAX時(shí),你也應(yīng)當(dāng)考慮其中帶來的后果。首先,所有應(yīng)用了AJAX的頁面無法加入書簽。隨著AJAX的使用,也為你的網(wǎng)站引入了一種“狀態(tài)”,而除了初始頁面外,用戶無法返回到任何其他頁面。 原因是在用戶的瀏覽器上url沒有改變-如果其發(fā)生改變,AJAX就沒有存在的必要了。 其次,如果想要支持每一位訪問網(wǎng)站的用戶,就需要付出雙倍的工作。對(duì)于你創(chuàng)建使用AJAX網(wǎng)站的每個(gè)片段,你都必須迎合沒有javascript功能用戶的需要。如果為了javascript和非javascript用戶具有相同的頁面級(jí)別,需要做大量額外的工作,必須使用noscript標(biāo)簽。也就是說,AJAX通過減少瀏覽和交互時(shí)所需要的頁面重載次數(shù),從而提高了網(wǎng)站的可用性。結(jié)合javascript效果庫,我們可以創(chuàng)建一些非常引人注目的頁面交互功能,這在兩年前是不可能實(shí)現(xiàn)的。因此,我的觀點(diǎn)是在你的網(wǎng)站的非主要位置使用AJAX。例如,在某個(gè)網(wǎng)站,如果將AJAX結(jié)構(gòu)應(yīng)用到文章中將是極其錯(cuò)誤的想法,因?yàn)槟阍僖矡o法將未讀完的文章加入書簽。另一方面,一種文章評(píng)論或?qū)υ捪到y(tǒng)則非常適合應(yīng)用AJAX。 責(zé)任編輯:張琎 |
|