無(wú)為

          無(wú)為則可為,無(wú)為則至深!

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

          閱讀提要 AJAX,一個(gè)異步JavaScript和XML的縮略詞,是當(dāng)今快速發(fā)展的Web開(kāi)發(fā)界十分熱門(mén)的技術(shù)。在這項(xiàng)新技術(shù)提供巨大能力的同時(shí),它也燃發(fā)了在"Back"按鈕問(wèn)題上的不容置疑的爭(zhēng)論。本文作者將向你解釋怎樣在真實(shí)世界中使用AJAX以及怎樣在一個(gè)工程中評(píng)估它的價(jià)值。在你讀完本文后,你就會(huì)明白什么是AJAX,在什么情況下,為什么以及怎樣使用這項(xiàng)技術(shù)。

            一、 簡(jiǎn)介

            AJAX,一個(gè)異步JavaScript和XML的縮略詞,是最近出來(lái)的技術(shù)詞語(yǔ)。異步意味著你可以經(jīng)由超文本傳輸協(xié)議(HTTP)向一個(gè)服務(wù)器發(fā)出請(qǐng)求并且在等待該響應(yīng)時(shí)繼續(xù)處理另外的數(shù)據(jù)。這就意味著,例如,你可以調(diào)用一個(gè)服務(wù)器端腳本來(lái)從一個(gè)數(shù)據(jù)庫(kù)中以XML方式檢索數(shù)據(jù),把數(shù)據(jù)發(fā)送到存儲(chǔ)在一個(gè)數(shù)據(jù)庫(kù)的服務(wù)器腳本,或者簡(jiǎn)單地裝載一個(gè)XML文件以填充你的Web站點(diǎn)而不需刷新該頁(yè)面。然而,在這項(xiàng)新技術(shù)提供巨大能力的同時(shí),它也引起了在"Back"按鈕問(wèn)題上的很多爭(zhēng)論。本文將幫助你確定在真實(shí)世界中何時(shí)使用AJAX是最佳選擇。

            首先,我假定你對(duì)縮略詞JavaScript和XML部分有一個(gè)基本了解。盡管你能通過(guò)AJAX請(qǐng)求任何類(lèi)型的文本文件,但是我在此主要集中討論XML。我將解釋怎樣在真實(shí)世界中使用AJAX以及怎樣在一個(gè)工程中評(píng)估它的價(jià)值。在你讀完本文后,你將會(huì)明白什么是AJAX,在什么情況下,為什么以及怎樣使用這項(xiàng)技術(shù)。你將要學(xué)習(xí),在保持給用戶提供直觀體驗(yàn)的同時(shí)怎樣創(chuàng)建對(duì)象,發(fā)出請(qǐng)求以及定制響應(yīng)。

            我已創(chuàng)建了一個(gè)適合于本文的示例工程(你可以下載源代碼)。這個(gè)示例實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的請(qǐng)求-它裝載一個(gè)包含頁(yè)面內(nèi)容的XML文件并且分析數(shù)據(jù)以把它顯示在一個(gè)HTML頁(yè)面中。

            二、 常規(guī)屬性和方法

            表1和2提供了一個(gè)屬性和方法的概述-它們?yōu)閃indows Internet Explorer 5,Mozilla,Netscape 7,Safari 1.2,和Opera等瀏覽器所支持。

            表1屬性

          屬性 描述
          onreadystatechange? 當(dāng)請(qǐng)求對(duì)象變化時(shí)該事件處理器激活。
          readyState? 返回指示對(duì)象的當(dāng)前狀態(tài)的值。
          responseText 來(lái)自服務(wù)器的響應(yīng)串的版本。
          responseXML? 來(lái)自服務(wù)器的響應(yīng)的DOM兼容的文檔對(duì)象。
          status 來(lái)自服務(wù)器的響應(yīng)的狀態(tài)碼。
          statusText 以一個(gè)字符串形式返回的狀態(tài)消息。

            表2方法

          方法 描述
          Abort() 取消當(dāng)前HTTP請(qǐng)求。
          getAllResponseHeaders() 檢索所有的HTTP頭值。
          getResponseHeader("headerLabel")? 從響應(yīng)體中檢索一個(gè)HTTP頭部的值。
          open("method","URL"[,asyncFlag[,"userName"[,"password"]]])? 初始化一個(gè)MSXML2.XMLHTTP請(qǐng)求,并從該請(qǐng)求指定方法,URL和認(rèn)證信息。
          send(content)? 發(fā)送一個(gè)HTTP請(qǐng)求到服務(wù)器并接收響應(yīng)。
          setRequestHeader("label", "value") 指定一個(gè)HTTP頭的名字。

            三、 從哪里開(kāi)始

            首先,你需要?jiǎng)?chuàng)建XML文件-后面我們對(duì)之進(jìn)行請(qǐng)求并作為頁(yè)面內(nèi)容進(jìn)行分析。你正在請(qǐng)求的文件必須與目標(biāo)工程駐留在相同的服務(wù)器上。

            下一步,創(chuàng)建發(fā)出請(qǐng)求的HTML文件。當(dāng)頁(yè)面通過(guò)使用頁(yè)面主體中的onload方法進(jìn)行加載時(shí),該請(qǐng)求發(fā)生。接著,該文件需要一個(gè)有ID的div標(biāo)簽,這樣當(dāng)我們準(zhǔn)備好要顯示內(nèi)容時(shí)就可以對(duì)之進(jìn)行定位。當(dāng)你做完所有這些,你的頁(yè)面的主體看上去如下:

          <body onload="makeRequest(′xml/content.xml′);">
          <div id="copy"></div>
          </body>

            四、 創(chuàng)建請(qǐng)求對(duì)象

            為了創(chuàng)建請(qǐng)求對(duì)象,你必須檢查是否瀏覽器使用XMLHttpRequest或ActiveXObject。這兩個(gè)對(duì)象之間的主要區(qū)別在于使用它們的瀏覽器。Windows IE 5 及以上版本使用ActiveX對(duì)象;而Mozilla,Netscape 7,Opera和Safari 1.2及以上版本使用XMLHttpRequest對(duì)象。另外一個(gè)區(qū)別是你創(chuàng)建對(duì)象的方式:Opera,Mozilla,Netscape和Safari允許你簡(jiǎn)單地調(diào)用該對(duì)象的構(gòu)造器,但是Windows IE需要把對(duì)象的名字傳遞到ActiveX構(gòu)造器中。下面是怎樣創(chuàng)建代碼來(lái)決定要使用哪個(gè)對(duì)象和怎樣創(chuàng)建它的示例:

          if(window.XMLHttpRequest)
          { request = new XMLHttpRequest();}
          else if(window.ActiveXObject)
          { request = new ActiveXObject("MSXML2.XMLHTTP");}
          五、 發(fā)出請(qǐng)求

            現(xiàn)在既然你已經(jīng)創(chuàng)建了你的請(qǐng)求對(duì)象,那么你已經(jīng)為向服務(wù)器發(fā)出請(qǐng)求作了準(zhǔn)備。創(chuàng)建一個(gè)到事件處理器的參考以聽(tīng)取onreadystatechange事件。然后,該事件處理器方法將在狀態(tài)發(fā)生變化時(shí)作出響應(yīng)。一旦我們完成請(qǐng)求,我們就開(kāi)始創(chuàng)建這個(gè)方法。打開(kāi)連接以GET或POST一個(gè)定制的URL-在此是一個(gè)content.xml,并且設(shè)置一個(gè)布爾定義-是否你想要進(jìn)行異步調(diào)用。

            現(xiàn)在到了發(fā)出請(qǐng)求的時(shí)間了。在這個(gè)示例中,我使用了null,因?yàn)槲覀兪褂玫氖荊ET;為了使用POST,你需要使用下面這個(gè)方法發(fā)出一個(gè)查詢串:

          request.onreadystatechange = onResponse;
          request.open("GET". url, true);
          request.send(null);

            六、 定制加載和錯(cuò)誤處理消息

            你為onreadystatechange方法創(chuàng)建的事件處理器正是集中進(jìn)行加載和處理錯(cuò)誤的場(chǎng)所。現(xiàn)在到了考慮用戶并針對(duì)他們與之交互的內(nèi)容的狀態(tài)提供反饋的時(shí)候了。在這個(gè)實(shí)例中,我針對(duì)所有的裝載狀態(tài)代碼提供反饋,并且也對(duì)最經(jīng)常發(fā)生的錯(cuò)誤處理狀態(tài)代碼提供一些基本的反饋。為了顯示請(qǐng)求對(duì)象的當(dāng)前狀態(tài),readyState屬性包括顯示在下表中的一些值。

          描述
          0 未初始化,對(duì)象沒(méi)有用數(shù)據(jù)進(jìn)行初始化。
          1 裝載中,對(duì)象正在裝載它的數(shù)據(jù)。
          2 裝載結(jié)束,對(duì)象完成了它的數(shù)據(jù)的裝載。
          3 可交互,用戶能與對(duì)象交互了,盡管它還沒(méi)有裝載結(jié)束。
          4 完成,對(duì)象已經(jīng)完全被初始化。

            W3C中有很長(zhǎng)的一串有關(guān)HTTP狀態(tài)代碼的定義。我選擇了兩個(gè)狀態(tài)代碼:

            ·200:請(qǐng)求成功了。

            ·404:服務(wù)器沒(méi)有找到與所請(qǐng)求的文件相匹配的任何東西。

            最后,我檢查任何另外的狀況代碼-它們將生成一個(gè)錯(cuò)誤并提供一個(gè)一般錯(cuò)誤信息。下面是一個(gè)代碼示例-你可以用之來(lái)處理這些情況。注意,我在定位我們前面在HTML文件的主體中創(chuàng)建的div ID并且對(duì)它應(yīng)用裝載和/或錯(cuò)誤信息-通過(guò)innerHTML方法-這個(gè)方法用于設(shè)置在div對(duì)象的開(kāi)始和結(jié)束標(biāo)簽之間的HTML:

          if(obj.readyState == 0)
          { document.getElementById(′copy′).innerHTML = "Sending Request...";}
          if(obj.readyState == 1)
          { document.getElementById(′copy′).innerHTML = "Loading Response...";}
          if(obj.readyState == 2)
          { document.getElementById(′copy′).innerHTML = "Response Loaded...";}
          if(obj.readyState == 3)
          { document.getElementById(′copy′).innerHTML = "Response Ready...";}
          if(obj.readyState == 4){
          if(obj.status == 200){ return true; }
          else if(obj.status == 404)
          {
          // 添加一個(gè)定制消息或把用戶重定向到另外一個(gè)頁(yè)面
          document.getElementById(′copy′).innerHTML = "File not found";
          }
          else
          {document.getElementById(′copy′).innerHTML = "There was a problem retrieving the XML."; }
          }

            當(dāng)狀況代碼為200時(shí),這意味著請(qǐng)求成功。下面開(kāi)始進(jìn)行響應(yīng)了。

            七、分析響應(yīng)

            當(dāng)你準(zhǔn)備好分析來(lái)自請(qǐng)求對(duì)象的響應(yīng)時(shí),真正的工作開(kāi)始了。現(xiàn)在你可以用你請(qǐng)求的數(shù)據(jù)開(kāi)始工作。僅為測(cè)試目的,在開(kāi)發(fā)期間,可以使用responseText和responseXML屬性來(lái)顯示來(lái)自響應(yīng)的原始數(shù)據(jù)。為了存取XML響應(yīng)中的結(jié)點(diǎn),首先使用你創(chuàng)建的請(qǐng)求對(duì)象,定位到responseXML屬性以檢索(你可能已經(jīng)猜測(cè)出來(lái))來(lái)自響應(yīng)的XML。定位到documentElement-它檢索一個(gè)到XML響應(yīng)的根結(jié)點(diǎn)的參考。

          var response = request.responseXML.documentElement;

            現(xiàn)在既然你有了到響應(yīng)的根結(jié)點(diǎn)的參考,那么你可以使用getElementsByTagName()以結(jié)點(diǎn)名字來(lái)檢索childNodes。下面一行用一個(gè)頭部的nodeName來(lái)定位一個(gè)childNode:

          response.getElementsByTagName(′header′)[0].firstChild.data;

            使用firstChild.data可以允許你存取該元素中的文本:

          response.getElementsByTagName(′header′)[0].firstChild.data;

            下面是怎樣創(chuàng)建這些代碼的完整的例子:

          var response = request.responseXML.documentElement;
          var header = response.getElementsByTagName(′header′)[0].firstChild.data;
          document.getElementById(′copy′).innerHTML = header;

            八、需求分析

            現(xiàn)在既然你知道怎樣使用AJAX的基礎(chǔ)知識(shí),那么下一步就是決定是否在一工程使用它。須記住的最重要的事情是,在你還沒(méi)有刷新頁(yè)面時(shí)你無(wú)法使用"Back"按鈕。為此,可以先專注于你的工程中的一小部分-它能夠從使用這種類(lèi)型的交互中受益。例如,你可以創(chuàng)建一個(gè)表單-它在用戶每次輸入一個(gè)輸入字段或一個(gè)字母時(shí)查詢一個(gè)腳本以便進(jìn)行實(shí)時(shí)校驗(yàn)。你可以創(chuàng)建一個(gè)拖放頁(yè)面-在釋放一項(xiàng)時(shí),它能夠把數(shù)據(jù)發(fā)送到一個(gè)腳本中并把該頁(yè)面的狀態(tài)保存到一個(gè)數(shù)據(jù)庫(kù)中。使用AJAX的理由毫無(wú)疑問(wèn)是存在的;并且這種使用無(wú)論對(duì)開(kāi)發(fā)者還是用戶都會(huì)帶來(lái)益處;這全依賴于具體的條件和執(zhí)行情況。

            還有其它方法可用來(lái)解決"Back"按鈕的問(wèn)題,例如使用Google Gmail-它現(xiàn)在能夠?yàn)槟愕牟僮魈峁┮环N撤消功能而不刷新該頁(yè)面。以后還會(huì)出現(xiàn)許多更具創(chuàng)造性的例子-它們將通過(guò)提供給開(kāi)發(fā)者創(chuàng)建獨(dú)特實(shí)時(shí)的體驗(yàn)的手段給用戶帶來(lái)更大的好處。

            九、結(jié)論

            盡管AJAX允許我們構(gòu)建新的和改進(jìn)的方式來(lái)與一個(gè)WEB頁(yè)面進(jìn)行交互;但是作為開(kāi)發(fā)者,我們需要牢記產(chǎn)品是不考慮技術(shù)的;它關(guān)心的是用戶以及其如何與用戶進(jìn)行交互。沒(méi)有了用戶群,我們構(gòu)建的工程毫無(wú)用處。基于這個(gè)標(biāo)準(zhǔn),我們就能評(píng)估應(yīng)該使用什么技術(shù)以及何時(shí)使用它們來(lái)創(chuàng)建對(duì)相應(yīng)用戶有用的應(yīng)用軟件。

          凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
          、轉(zhuǎn)載請(qǐng)注明來(lái)處和原文作者。非常感謝。

          posted on 2006-06-24 14:10 草兒 閱讀(174) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): ajax
          主站蜘蛛池模板: 赤壁市| 宝丰县| 泽库县| 刚察县| 吉林市| 阳新县| 丰都县| 镇坪县| 梁平县| 定陶县| 临城县| 长阳| 宁远县| 德化县| 洛南县| 临沂市| 澎湖县| 寻乌县| 巍山| 汝州市| 靖远县| 福海县| 宁德市| 牟定县| 兴和县| 虞城县| 姚安县| 同心县| 房产| 浙江省| 桦川县| 连江县| 永善县| 古丈县| 岗巴县| 和平县| 上栗县| 栾城县| 清涧县| 宜黄县| 富阳市|