小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

如何使用AJAX

 kaichun 2006-08-18

初次接觸AJAX的開發(fā)人員一定很關(guān)心:如何在實際環(huán)境中使用 AJAX,以及如何評估它在項目中的價值。本文從基本操作入手,結(jié)合模擬實例,由淺入深介紹了AJAX的入門之道。

AJAX入門

● 如何發(fā)送HTTP請求

為了使用JavaScript向服務(wù)器發(fā)送HTTP請求,需要為提供這種功能的類創(chuàng)建實例。這種類最先作為ActiveX對象: XMLHTTP被引入到Internet Explorer里面。后來,Mozilla、Safari及其他瀏覽器紛紛仿效,實現(xiàn)了XMLHttpRequest類,支持微軟的原始ActiveX對象所具有的方法和屬性。

因此,為了為所需的類創(chuàng)建跨瀏覽器的實例(對象),可編寫如下代碼。(為了便于闡述,該代碼是用于創(chuàng)建XMLHTTP實例的簡化版。)

if (window.XMLHttpRequest) { // Mozilla, Safari, ...

http_request = new XMLHttpRequest();

} else if (window.ActiveXObject) { // IE

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

}

如果來自服務(wù)器的響應(yīng)沒有XML mime-type頭,一些Mozilla瀏覽器的某些版本可能無法正常工作。為了解決這個問題,如果服務(wù)器發(fā)送的頭不是text/xml,可調(diào)用另外方法來忽略該頭。

http_request = new XMLHttpRequest();

http_request.overrideMimeType(‘text/xml‘);

下一步就是確定收到服務(wù)器對請求的響應(yīng)后,需要做什么。在這個階段,需要告訴HTTP請求對象: 哪個JavaScript函數(shù)將完成處理響應(yīng)的工作??梢园褜ο蟮膐nreadystatechange屬性設(shè)成準備使用的JavaScript的函數(shù)的名稱,如下所示:

http_request.onreadystatechange = nameOfTheFunction;

注意,函數(shù)名后面沒有方括號,也無需傳遞參數(shù)。另外,可以使用迅速定義函數(shù)的Javascript技術(shù),定義會立即處理響應(yīng)的動作,而不是賦予函數(shù)名,如下所示:

http_request.onreadystatechange = function(){

// 完成工作};

聲明了一旦收到響應(yīng)會發(fā)生什么動作后,就要實際發(fā)送請求了。需要調(diào)用HTTP請求類的open()和send()方法,如下所示:

http_request.open(‘GET‘, ‘http://www./some.file‘, true);

http_request.send(null);

open()調(diào)用的第一個參數(shù)是HTTP請求方法——GET、POST、HEAD或者其他任何得到服務(wù)器支持的方法。按照HTTP標準,方法需要大寫,否則,有些瀏覽器(如Firefox)可能無法處理請求。第二個參數(shù)是請求頁面的URL。作為一項安全特性,無法調(diào)用第三方域名上的頁面。所有頁面上務(wù)必使用準確的域名,否則如果調(diào)用open(),會得到“權(quán)限被拒絕”的錯誤提示。一個常見的錯誤就是按照domain.tld來訪問網(wǎng)站,卻試圖使用www.domain.tld調(diào)用頁面。第三個參數(shù)確定了請求是不是異步模式。如果是TRUE,那么即使服務(wù)器響應(yīng)還沒有到達,JavaScript函數(shù)仍繼續(xù)執(zhí)行。這就是AJAX中的“A”。

如果請求方法是POST,那么send()方法的參數(shù)可以是想發(fā)送給服務(wù)器的任何數(shù)據(jù)。數(shù)據(jù)應(yīng)當采用查詢字符串的格式,如下所示:

name=value&anothername=othervalue&so=on

注意,如果想使用POST發(fā)送請求,必須使用以下代碼行來改變請求的MIME類型,否則,服務(wù)器會丟棄通過POST發(fā)送的數(shù)據(jù)。

http_request.setRequestHeader(‘Content-Type‘, ‘a(chǎn)pplication/x-www-form-urlencoded‘);

● 處理服務(wù)器響應(yīng)

切記,在發(fā)送請求時,要提供旨在處理響應(yīng)的JavaScript函數(shù)的名稱。

http_request.onreadystatechange = nameOfTheFunction;

不妨看一下這個函數(shù)的功能。首先,函數(shù)需要檢查請求的狀態(tài)。如果狀態(tài)的值為4,就意味著完整的服務(wù)器響應(yīng)已收到,可以繼續(xù)處理響應(yīng)。readyState值如下: 0(未初始化)、1(正在加載)、2(加載完畢)、3(可以交互)、4(完成)。

if (http_request.readyState == 4) {

// 一切正常,響應(yīng)已收到

} else {

// 還沒有就緒

}

下一步就是檢查HTTP服務(wù)器響應(yīng)的狀態(tài)代碼。所有可能的狀態(tài)代碼都列在W3C的網(wǎng)站上(http://www./Protocols/rfc2616/rfc2616-sec10.html)。這里只對200 OK響應(yīng)感興趣。

if (http_request.status == 200) {

// 非常好!

} else {

// 請求有問題,

// 譬如響應(yīng)可能是404(未發(fā)現(xiàn))

// 或者500(內(nèi)部服務(wù)器錯誤)響應(yīng)代碼

}

檢查了請求狀態(tài)及響應(yīng)的HTTP狀態(tài)代碼后,就可以對服務(wù)器發(fā)送過來的數(shù)據(jù)進行各種處理了。有兩種方式來訪問該數(shù)據(jù): 一是http_request.responseText,將返回文本字符串形式的服務(wù)器響應(yīng); 二是http_request.responseXML,將返回XMLDocument對象形式的響應(yīng)??梢杂肑avaScript DOM函數(shù)來遍歷XMLDocument對象。

● 簡單示例

我們把所有部分結(jié)合起來,發(fā)送簡單的HTTP請求。我們的JavaScript將請求一個HTML文檔: test.html,該文檔包含“I‘m a test.”文本,然后我們用alert()方法顯示test.html文件的內(nèi)容。

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

var http_request = false;

function makeRequest(url) {

http_request = false;

if (window.XMLHttpRequest) { // Mozilla, Safari,...

http_request = new XMLHttpRequest();

if (http_request.overrideMimeType) {

http_request.overrideMimeType(‘text/xml‘); }

} else if (window.ActiveXObject) { // IE

try {

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

} catch (e) {

try {

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

} catch (e) {}

}

}

if (!http_request) {

alert(‘Giving up :( Cannot create an XMLHTTP instance‘);

return false; }

http_request.onreadystatechange = alertContents;

http_request.open(‘GET‘, url, true);

http_request.send(null);

}

function alertContents() {

if (http_request.readyState == 4) {

if (http_request.status == 200) {

alert(http_request.responseText);

} else {

alert(‘There was a problem with the request.‘); }

}

}

< /script>

< span

style="cursor: pointer; text-decoration: underline"

onclick="makeRequest(‘test.html‘)">

Make a request

< /span>

在這個示例中,用戶點擊瀏覽器上面的“發(fā)送請求”鏈接; 調(diào)用makeRequest()函數(shù),參數(shù)是同一目錄下的HTML文件名: test.html; 請求被發(fā)送,然后onreadystatechange執(zhí)行結(jié)果被傳遞給alertContents();

alertContents()檢查響應(yīng)是否被收到、是否正常,然后用alert()方法顯示test.html文件的內(nèi)容。

如果XMLHttpRequest調(diào)用的頁面不是有效的XML(譬如不是明文),上面的代碼行“http_request.overrideMimeType(‘text/xml‘);”就會導致Firefox 1.5b里面出現(xiàn)Javascript 控制臺錯誤信息。如果瀏覽器上出現(xiàn)了“語法錯誤”或者“不規(guī)范的錯誤”,而且不是試圖從XMLHttpRequest加載XML頁面,請從代碼中刪除該行。

另外,如果把請求發(fā)送到將返回XML的一段代碼,而不是發(fā)送到靜態(tài)的XML文件,要是頁面在Mozilla和IE瀏覽器中都能正常工作,就必須設(shè)置一些響應(yīng)頭。如果沒有設(shè)置頭: “Content-Type: application/xml”,IE會在試圖訪問XML元素的那一行后面拋出Javascript錯誤: “Object Expected”。如果沒有設(shè)置頭: “Cache-Control: no-cache”,瀏覽器就會緩存響應(yīng),永遠不會重新提交請求。這樣一來,調(diào)試起來就會難度很大。

● 處理XML響應(yīng)

在前一個示例中,收到HTTP請求的響應(yīng)后,我們使用了請求對象的reponseText屬性,該屬性包含test.html文件的內(nèi)容?,F(xiàn)在我們來試一試responseXML屬性。

首先,我們創(chuàng)建一個有效的XML文檔,隨后我們將對其發(fā)出請求。該文檔(test.xml)含有以下代碼:

< ?xml version="1.0" ?>

I‘m a test.

在腳本中,我們只要修改請求代碼行:

onclick="makeRequest(‘test.xml‘)">

然后在alertContents()中,我們需要把alert()代碼行alert(http_request.responseText):

var xmldoc = http_request.responseXML;

var root_node = xmldoc.getElementsByTagName(‘root‘).item(0);

alert(root_node.firstChild.data);

這樣一來,我們獲得了responseXML提供的XMLDocument對象,然后我們使用DOM方法訪問XML文件里面所含的一些數(shù)據(jù)。

何時使用AJAX

已經(jīng)知道了AJAX的基本知識,下一步無疑就是確定要不要在項目中使用它。要記住的最重要一點就是,如果沒有刷新頁面,就無法使用“后退”按鈕。要把注意力集中于項目中可能得益于使用這種交互的一小部分。譬如說,可以創(chuàng)建一個表單: 每當用戶鍵入輸入字段,或者鍵入字母,就可以查詢腳本,以便提供實時驗證功能??梢詣?chuàng)建拖放頁面: 一釋放項目,就可以把數(shù)據(jù)發(fā)送到腳本中,并把頁面狀態(tài)保存到數(shù)據(jù)庫?,F(xiàn)在確實存在使用AJAX的理由,這不但有助于開發(fā)體驗,還有助于用戶,它完全取決于實際情況和執(zhí)行狀況。

還有其他方法可以避開“后退”按鈕方面的問題,譬如使用Google Gmail: 它現(xiàn)在可以為已經(jīng)完成的操作步驟提供撤消功能,用不著刷新頁面。以后肯定會出現(xiàn)許多更有創(chuàng)意的例子,為開發(fā)人員提供諸多方法來創(chuàng)建獨特、實時的體驗,從而讓用戶成為受益者。

假定讀者已經(jīng)對AJAX的JavaScript和XML兩個部分有一定了解。雖然開發(fā)人員可以通過AJAX請求任何類型的文本文件,但這里將著重討論XML類型。本文創(chuàng)建了一個示例項目。這個示例是一個簡單的請求,要求加載含有頁面內(nèi)容的XML文件,然后解析數(shù)據(jù),把它顯示在HTML頁面上。

表1和表2介紹了Windows Internet Explorer 5、Mozilla、Netscape 7、Safari 1.2和Opera支持的屬性和方法。

● 從何處開始

首先,需要創(chuàng)建一個XML文件,隨后我們會對其進行請求,并作為頁面內(nèi)容來解析。這里請求的那個文件必須與完成的項目位于同一服務(wù)器上。

下一步,創(chuàng)建將發(fā)出請求的HTML文件。頁面使用主體標記中的裝載方法進行裝載時,就會發(fā)生請求。然后,文件需要帶有ID的div標記,那樣我們準備好顯示內(nèi)容后,就可以確定目標。完成了這些步驟后,頁面主體的樣子應(yīng)當如下:

<body onload="makeRequest(‘xml/content.xml‘);">

<div id="copy"></div>

</body>

● 創(chuàng)建請求對象

為了創(chuàng)建請求對象,必須檢查瀏覽器使用的是XMLHttpRequest還是ActiveXObject。這兩個對象之間的區(qū)別主要在于使用它們的瀏覽器。Windows IE 5 及以上版本使用ActiveX對象; 而Mozilla、Netscape 7、Opera和Safari 1.2及以上版本使用XMLHttpRequest對象。另一個區(qū)別在于創(chuàng)建對象的方式: Opera、Mozilla、Netscape和Safari允許只要調(diào)用該對象的構(gòu)造函數(shù),但Windows IE需要將對象名稱傳遞到ActiveX構(gòu)造函數(shù)中。下面這個示例表明了如何編寫代碼來確定使用哪個對象、如何創(chuàng)建對象:

if(window.XMLHttpRequest)

{ request = new XMLHttpRequest();}

else if(window.ActiveXObject)

{ request = new ActiveXObject("MSXML2.XMLHTTP");}

● 發(fā)出請求

請求對象創(chuàng)建好后,就可以準備向服務(wù)器發(fā)出請求了。為事件處理器創(chuàng)建引用,以偵聽onreadystatechange。隨后,事件處理器方法在狀態(tài)發(fā)生變化時會做出響應(yīng)。一旦完成了請求,就可以創(chuàng)建這個方法。打開連接,GET或者POST定制的URL——這里是content.xml,然后設(shè)置布爾值,定義是否希望調(diào)用異步調(diào)用。

現(xiàn)在可以發(fā)出請求了。示例中使用了null,因為我們用的是GET; 想用POST,則需要用這個方法發(fā)送一個查詢字符串:

request.onreadystatechange = onResponse;

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

request.send(null);

● 定制加載和錯誤處理消息

為onreadystatechange方法創(chuàng)建的事件處理器是專門負責加載及錯誤處理的地方。在示例中,為所有加載狀態(tài)代碼提供了反饋,還為最經(jīng)常發(fā)生的錯誤處理狀態(tài)代碼提供了一些基本反饋。為了顯示請求對象的當前狀態(tài),readyState屬性包括表3中顯示的一些值。

W3C詳細列出了HTTP狀態(tài)代碼的定義。我選擇了其中兩個狀態(tài)代碼: 200,請求已成功; 404,服務(wù)器沒有找到與請求文件相匹配的任何東西。

最后,我們檢查了會生成錯誤并提供一般錯誤信息的其他狀態(tài)代碼。下面是一個代碼示例,可以用該代碼處理這些情況。不過要注意,這里把目標定于我們在HTML文件的主體中創(chuàng)建的div ID,并且使用innerHTML方法,添加了裝載以及/或者錯誤消息——該方法設(shè)置了div對象的開始和結(jié)束標記之間的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)

{

// 把定制消息添加到另一個頁面上,或者把用戶重定向到另一個頁面上

document.getElementById(‘copy‘).innerHTML = "File not found";

}

else

{document.getElementById(‘copy‘).innerHTML = "There was a problem retrieving the XML."; }

}

如果狀況代碼為200,這意味著請求成功,響應(yīng)可以隨時準備解析了。

● 解析響應(yīng)

準備好解析請求對象的響應(yīng)時,真正的工作開始了。這時候就可以真正開始處理所請求的數(shù)據(jù)了。為了便于在開發(fā)過程中進行測試,responseText和responseXML屬性可用來顯示來自響應(yīng)的原始數(shù)據(jù)。為了開始訪問XML響應(yīng)中的節(jié)點,先從已創(chuàng)建的請求對象入手,定位responseXML屬性,檢索來自響應(yīng)的XML。然后定位documentElement,它會檢索XML響應(yīng)的根節(jié)點的引用。

var response = request.responseXML.documentElement;

已經(jīng)有了響應(yīng)根節(jié)點的引用,這時你可以使用getElementsByTagName(),按節(jié)點名稱來檢索childNodes。下面一行用頭的nodeName來定位childNode:

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

使用firstChild.data就可以訪問元素里面的文本:

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

以下是如何編寫代碼的完整示例:

var response = request.responseXML.documentElement;

var header = response.getElementsByTagName(‘header‘)[0].firstChild.data;

document.getElementById(‘copy‘).innerHTML = header; (沈建苗編譯)

雖然AJAX允許我們以新穎的方式與網(wǎng)頁進行交互,可是作為開發(fā)人員,我們需要牢記產(chǎn)品并不單單涉及技術(shù),還涉及用戶以及他們?nèi)绾闻c產(chǎn)品進行交互。要是沒有用戶,我們構(gòu)建的項目將毫無用處。如果時時考慮到這條準則,我們就能評估使用什么技術(shù)、何時使用它們,從而創(chuàng)建有助于所有使用者的應(yīng)用程序。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多