![使用XMLHttpRequest對象_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/31/084fd103-4837-4fce-b0cb-50119bf6340a/084fd103-4837-4fce-b0cb-50119bf6340a1.gif)
![使用XMLHttpRequest對象_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/31/084fd103-4837-4fce-b0cb-50119bf6340a/084fd103-4837-4fce-b0cb-50119bf6340a2.gif)
![使用XMLHttpRequest對象_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/31/084fd103-4837-4fce-b0cb-50119bf6340a/084fd103-4837-4fce-b0cb-50119bf6340a3.gif)
![使用XMLHttpRequest對象_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/31/084fd103-4837-4fce-b0cb-50119bf6340a/084fd103-4837-4fce-b0cb-50119bf6340a4.gif)
![使用XMLHttpRequest對象_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/31/084fd103-4837-4fce-b0cb-50119bf6340a/084fd103-4837-4fce-b0cb-50119bf6340a5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第2章 使用XMLHttpRequest對象我們已經(jīng)討論了動(dòng)態(tài)Web應(yīng)用的發(fā)展歷史,并簡要介紹了Ajax,下面再來討論問題的關(guān)鍵:如何使用XMLHttpRequest對象。盡管Ajax不只是一個(gè)技術(shù),更應(yīng)是一種技巧,但如果沒有對XMLHttpRequest的廣泛支持,Google Suggest和Ta-da List可能不會(huì)像我們看到的有今天這樣的發(fā)展。而你可能也不會(huì)看手上的這本書!XMLHttpRequest最早在Internet Explorer 5中實(shí)現(xiàn)為ActiveX組件。由于只能在Internet Explorer中使用,所以大多數(shù)開發(fā)人員都沒有用XMLHttpRequest,直到最
2、近Mozilla 1.0和Safari 1.2把它采用為事實(shí)上的標(biāo)準(zhǔn),情況才有改觀。需要說明重要的一點(diǎn), XMLHttpRequest并不是一個(gè)W3C標(biāo)準(zhǔn),不過許多功能已經(jīng)涵蓋在一個(gè)新提案中:DOM Level 3加載和保存規(guī)范(DOM Level 3 Load and Save Specification)。因?yàn)樗皇且粋€(gè)標(biāo)準(zhǔn),所以在不同瀏覽器上的表現(xiàn)可能稍有區(qū)別,不過大多數(shù)方法和屬性都得到了廣泛的支持。當(dāng)前,F(xiàn)irefox、Safari、Opera、Konqueror和Internet Explorer都以類似的方式實(shí)現(xiàn)了XMLHttpRequest對象的行為。前面已經(jīng)說過,如果大量用戶還
3、是在用較老的瀏覽器訪問你的網(wǎng)站或應(yīng)用,就要三思了。第1章討論過,在這種情況下,如果要使用Ajax技術(shù),就要么需要開發(fā)一個(gè)候選網(wǎng)站,要么你的應(yīng)用應(yīng)當(dāng)能妥善地降級。大多數(shù)使用統(tǒng)計(jì)表明,當(dāng)前使用的瀏覽器中,只有極少數(shù)不支持XMLHttpRequest,所以一般情況下不會(huì)存在這個(gè)問題。不過,還是應(yīng)該查看Web日志,確定你的用戶在使用什么樣的客戶端來訪問你的網(wǎng)站。 1.1 XMLHttpRequest對象概述在使用XMLHttpRequest對象發(fā)送請求和處理響應(yīng)之前,必須先用JavaScript創(chuàng)建一個(gè)XMLHttpRequest對象。由于XMLHttpRequest不是一個(gè)W3C標(biāo)準(zhǔn),所以可以采用多
4、種方法使用JavaScript來創(chuàng)建XMLHttpRequest的實(shí)例。Internet Explorer把XMLHttpRequest實(shí)現(xiàn)為一個(gè)ActiveX對象,其他瀏覽器(如Firefox、Safari和Opera)會(huì)把它實(shí)現(xiàn)為一個(gè)本地JavaScript對象。由于存在這樣一些差別,JavaScript代碼中必須包含有關(guān)的邏輯,從而使用ActiveX技術(shù)或者使用本地JavaScript技術(shù)來創(chuàng)建XMLHttpRequest的一個(gè)實(shí)例。很多人可能還記得從前的那段日子,那時(shí)不同瀏覽器上的JavaScript和DOM實(shí)現(xiàn)簡直千差萬別,聽了上面這段話之后,這些人可能又會(huì)不寒而栗。幸運(yùn)的是,在這里
5、為了明確該如何創(chuàng)建XMLHttpRequest對象的實(shí)例,并不需要那么詳細(xì)地編寫代碼來區(qū)別瀏覽器類型。你要做的只是檢查瀏覽器是否提供對ActiveX對象的支持。如果你的瀏覽器支持ActiveX對象,就使用ActiveX來創(chuàng)建XMLHttpRequest對象。否則,就要使用本地JavaScript對象技術(shù)來創(chuàng)建。代碼清單2-1展示了編寫跨瀏覽器的JavaScript代碼來創(chuàng)建XMLHttpRequest對象實(shí)例是多么的簡單。代碼清單2-1創(chuàng)建XMLHttpRequest對象的一個(gè)實(shí)例var xmlHttp;function createXMLHttpRequest() if (window.Ac
6、tiveXObject) xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");else if (window.XMLHttpRequest) xmlHttp = new XMLHttpRequest();可以看到,創(chuàng)建XMLHttpRequest對象相當(dāng)容易。首先,要?jiǎng)?chuàng)建一個(gè)全局作用域變量xmlHttp來保存這個(gè)對象的引用。createXMLHttpRequest方法完成創(chuàng)建XMLHttpRequest實(shí)例的具體工作。這個(gè)方法中只有簡單的分支邏輯(選擇邏輯),來確定如何創(chuàng)建對象。對window.ActiveXObject的調(diào)用會(huì)
7、返回一個(gè)對象,也可能返回null,if語句會(huì)把調(diào)用返回的結(jié)果看作是true或false(如果返回對象則為true,返回null則為false),以此指示瀏覽器是否支持ActiveX控件,相應(yīng)地得知瀏覽器是不是Internet Explorer。如果確實(shí)是,則實(shí)例化ActiveXObject的一個(gè)新實(shí)例來創(chuàng)建XMLHttpRequest對象,并傳入一個(gè)串指示要?jiǎng)?chuàng)建何種類型的ActiveX對象。在這個(gè)例子中,為構(gòu)造函數(shù)提供的串是Microsoft.XMLHTTP,這說明你想創(chuàng)建XMLHttpRequest的一個(gè)實(shí)例。如果window.ActiveXObject調(diào)用失?。ǚ祷豱ull),JavaSc
8、ript就會(huì)轉(zhuǎn)到else語句分支,確定瀏覽器是否把XMLHttpRequest實(shí)現(xiàn)為一個(gè)本地JavaScript對象。如果存在window.XMLHttpRequest,就會(huì)創(chuàng)建XMLHttpRequest的一個(gè)實(shí)例。由于JavaScript具有動(dòng)態(tài)類型特性,而且XMLHttpRequest實(shí)現(xiàn)在不同瀏覽器上是兼容的,所以可以以同樣的方式訪問XMLHttpRequest實(shí)例的屬性和方法,而不論這個(gè)實(shí)例是如何創(chuàng)建的。這就大大簡化了開發(fā)過程,而且在JavaScript中也不必編寫特定于瀏覽器的邏輯。1.2 方法和屬性表2-1顯示了XMLHttpRequest對象的一些典型方法。不要擔(dān)心;稍后就會(huì)詳
9、細(xì)介紹這些方法。表2-1標(biāo)準(zhǔn)XMLHttpRequest操作方法描述abort()停止當(dāng)前請求。(譯者注:原文此處不對)getAllResponseHeaders()把HTTP請求的所有響應(yīng)首部作為鍵/值對返回。getResponseHeader("header")返回指定首部的串值。open("method", "url")建立對服務(wù)器的調(diào)用。method(方法)參數(shù)可以是GET、POST或PUT。url參數(shù)可以是相對URL或絕對URL。這個(gè)方法還包括3個(gè)可選的參數(shù).send(content)向服務(wù)器發(fā)送請求。setRequestH
10、eader("header", "value")把指定首部設(shè)置為所提供的值。在設(shè)置任何首部之前必須先調(diào)用open()。下面來更詳細(xì)地討論這些方法。void open(string method, string url, boolean asynch, string username, string password):這個(gè)方法會(huì)建立對服務(wù)器的調(diào)用。這是初始化一個(gè)請求的純腳本方法。它有兩個(gè)必要的參數(shù),還有3個(gè)可選參數(shù)。要提供調(diào)用的特定方法(GET、POST或PUT),還要提供所調(diào)用資源的URL。另外還可以傳遞一個(gè)Boolean值,指示這個(gè)調(diào)用是異步還是同步
11、的,默認(rèn)值為true,這表示請求本質(zhì)上是異步的。如果這個(gè)參數(shù)為false,處理就會(huì)等待,直到從服務(wù)器返回響應(yīng)為止。由于異步調(diào)用是使用Ajax的主要優(yōu)點(diǎn)之一,所以倘若將這個(gè)參數(shù)設(shè)置為false,從某種程度上講與使用XMLHttpRequest對象的初衷不太相符。不過,前面已經(jīng)說過,在某些情況下這個(gè)參數(shù)設(shè)置為false也是有用的,比如在持久存儲頁面之前你可能想先驗(yàn)證用戶的輸入。最后兩個(gè)參數(shù)不說自明,允許你指定一個(gè)特定的用戶名和口令。void send(content):這個(gè)方法具體向服務(wù)器發(fā)出請求。如果請求聲明為異步的,這個(gè)方法就會(huì)立即返回,否則它會(huì)等待,直到接收到響應(yīng)為止。參數(shù)是可選的,可以是一
12、個(gè)DOM對象的實(shí)例、一個(gè)輸入流,或者是一個(gè)串。傳入這個(gè)對象的內(nèi)容會(huì)作為請求體的一部分發(fā)送。void setRequestHeader(string header, string value): 這個(gè)方法為HTTP請求中一個(gè)給定的首部設(shè)置值。它有兩個(gè)參數(shù),第一個(gè)串表示要設(shè)置的首部,第二個(gè)串表示要在首部中放置的值。需要說明,這個(gè)方法必須在open()之后才能調(diào)用。在所有這些方法中,最有可能用到的就是open()和send()。XMLHttpRequest對象還有許多屬性,在設(shè)計(jì)Ajax交互時(shí)這些屬性非常有用。void abort(): 顧名思義,這個(gè)方法就是要停止請求。string getAllR
13、esponseHeaders(): 這個(gè)方法的核心功能對Web應(yīng)用開發(fā)人員應(yīng)該很熟悉了,它會(huì)返回一個(gè)串,其中包含HTTP請求的所有響應(yīng)首部。首部包括Content-Length、Date和URI。string getResponseHeader(string header): 這個(gè)方法與getAllResponseHeaders()是對應(yīng)的,不過它有一個(gè)參數(shù)來表示你希望得到哪一個(gè)首部值,并且會(huì)把這個(gè)值作為一個(gè)串返回。除了這些標(biāo)準(zhǔn)方法,XMLHttpRequest對象還提供了許多屬性,如表2-2所示。處理XMLHttpRequest時(shí)可以大量使用這些屬性。表2-2標(biāo)準(zhǔn)XMLHttpRequest
14、屬性屬性描述onreadystatechange每個(gè)狀態(tài)改變時(shí)都會(huì)觸發(fā)這個(gè)事件處理器,通常會(huì)調(diào)用一個(gè)JavaScript函數(shù)。readyState請求的狀態(tài)。有5個(gè)可取值:0 = 未初始化,1 = 正在加載, 2 = 已加載, 3 = 交互中, 4 = 完成。responseText服務(wù)器的響應(yīng),表示為一個(gè)串。responseXML服務(wù)器的響應(yīng),表示為XML。這個(gè)對象可以解析為一個(gè)DOM對象。status服務(wù)器的HTTP狀態(tài)碼(200對應(yīng)OK,404對應(yīng)Not Found(未找到),等等)statusTextHTTP狀態(tài)碼的相應(yīng)文本(OK或Not Found(未找到)等等)。1.3 一個(gè)交互示
15、例看到這里,你可能想知道典型的Ajax交互是什么樣子。圖2-1顯示了Ajax應(yīng)用中標(biāo)準(zhǔn)的交互模式。圖見P261圖2-1標(biāo)準(zhǔn)Ajax交互圖中文字對照:Ajax-Enabled Web Application:使用Ajax的Web應(yīng)用Web Container:Web容器Event:事件Client:客戶Server:服務(wù)器Server Resource:服務(wù)器資源Data Store:數(shù)據(jù)庫不同于標(biāo)準(zhǔn)Web客戶中所用的標(biāo)準(zhǔn)請求/響應(yīng)方法,Ajax應(yīng)用的做法稍有點(diǎn)差別。1. 一個(gè)客戶端事件觸發(fā)一個(gè)Ajax事件。從簡單的onchange事件,到某個(gè)特定的用戶動(dòng)作,很多這樣的事件都可以觸發(fā)Ajax事件
16、??梢杂腥缦碌拇a:<input type="text"d="email" name="email" onblur="validateEmail()">2. 創(chuàng)建XMLHttpRequest對象的一個(gè)實(shí)例。使用open()方法建立調(diào)用,并設(shè)置URL以及所希望的HTTP方法(通常是GET或POST)。請求實(shí)際上通過一個(gè)send()方法調(diào)用觸發(fā)。代碼可能如下所示:var xmlHttp;function validateEmail() var email = document.getElementById(
17、"email");var url = "validate?email=" + escape(email.value);if (window.ActiveXObject) xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");else if (window.XMLHttpRequest) xmlHttp = new XMLHttpRequest();xmlHttp.open("GET", url);xmlHttp.onreadystatechange = callback;
18、xmlHttp.send(null);3. 向服務(wù)器做出請求??赡軙?huì)調(diào)用一個(gè)servlet、一個(gè)CGI腳本,或者使用任何其他服務(wù)器端技術(shù)。4. 服務(wù)器可以做你想做的事情,包括訪問數(shù)據(jù)庫,甚至訪問另一個(gè)系統(tǒng)。5. 請求返回到瀏覽器。Content-Type首部設(shè)置為text/xmlXMLHttpRequest對象只能處理text/html類型的結(jié)果。在另外一些的情況下,響應(yīng)可能更為復(fù)雜,還包括JavaScript、DOM管理以及其他相關(guān)的技術(shù)。需要說明,你還需要設(shè)置另外一些首部,使瀏覽器不會(huì)在本地緩存結(jié)果。為此可以使用下面的代碼:response.setHeader("Cache-Co
19、ntrol", "no-cache");response.setHeader("Pragma", "no-cache"); Pragma和Cache-Control它們不是一樣的嗎?不錯(cuò)是,它們是一樣的,不過定義Pragma是為了保證向后兼容。6. 在這個(gè)例子中,XMLHttpRequest對象配置為處理返回時(shí)要調(diào)用callback()函數(shù)。這個(gè)函數(shù)會(huì)檢查XMLHttpRequest對象的readyState屬性,然后查看服務(wù)器返回的狀態(tài)碼。如果一切正常,callback()函數(shù)就會(huì)在客戶端上做些有意思的工作。以下就是一個(gè)典
20、型的回調(diào)方法:function callback() if (xmlHttp.readyState = 4) if (xmlHttp.status = 200) /do something interesting here可以看到,這與正常的請求/響應(yīng)模式有所不同,但對Web開發(fā)人員來說,并不是完全陌生的。顯然,在創(chuàng)建和建立XMLHttpRequest對象時(shí)還可以做些事情,另外當(dāng)“回調(diào)”函數(shù)完成了狀態(tài)檢查之后也可以有所作為。一般地,你會(huì)把這些標(biāo)準(zhǔn)調(diào)用包裝在一個(gè)庫中,以便在整個(gè)應(yīng)用中使用,或者可以使用Web上提供的庫。這個(gè)領(lǐng)域還很新,但是開源群體中已經(jīng)如火如荼地展開了許多這方面的工作。通常,網(wǎng)上
21、有許多框架和工具包能負(fù)責(zé)基本的連接和瀏覽器抽象,有些還增加了用戶界面組件。有一些純粹基于客戶,還有一些需要服務(wù)器上的工作。這些框架很多只是剛剛才開始開發(fā),或者才發(fā)布不久;情況還在不斷發(fā)生變化,經(jīng)常會(huì)有新的庫和新的版本出現(xiàn)。隨著這個(gè)領(lǐng)域日漸成熟,孰優(yōu)孰劣就會(huì)很清楚了。一些比較成熟的庫包括libXmlRequest、RSLite、sarissa、JavaScript對象注解(JavaScript Object Notation,JSON)、JSRS、直接Web遠(yuǎn)程通信(Direct Web Remoting,DWR)和Rails的Ruby。這個(gè)領(lǐng)域日新月異,所以應(yīng)當(dāng)適當(dāng)?shù)嘏渲媚愕腞SS收集器,及時(shí)
22、收集有關(guān)Ajax的所有網(wǎng)站上的信息!1.4 GET vs. POST你可能不清楚GET和POST之間有什么區(qū)別,不知道在這兩種方法中該使用哪一個(gè)。理論上講,如果請求是冪等的(idempotent),就可以使用GET,所謂冪等是指多個(gè)同樣的請求返回的結(jié)果也一樣。實(shí)際上,相應(yīng)的服務(wù)器方法可能會(huì)以某種方式修改狀態(tài),所以一般情況下這是不成立的。這只是一種標(biāo)準(zhǔn)。更實(shí)際的區(qū)別在于負(fù)載的大小,在許多情況下,盡管能隨URL向服務(wù)器發(fā)送數(shù)據(jù),但瀏覽器和服務(wù)器會(huì)限制URL的長度。一般來講,可以使用GET從服務(wù)器獲取數(shù)據(jù);換句話說,要避免使用GET調(diào)用修改服務(wù)器上的狀態(tài)。一般地,要修改服務(wù)器上的狀態(tài)時(shí),就應(yīng)當(dāng)使用P
23、OST方法。不同于GET,要設(shè)置XMLHttpRequest對象的Content-Type首部,如下所示:xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");與GET不同,POST不會(huì)限制發(fā)送給服務(wù)器的負(fù)載的大小, 而且POST請求不能保證是冪等的。你做的大多數(shù)請求可能都是GET請求,不過,如果需要,也完全可以使用POST。1.5 遠(yuǎn)程腳本我們已經(jīng)介紹了Ajax,下面來簡單談?wù)勥h(yuǎn)程腳本。你可能會(huì)問“Ajax有什么大不了的?我早就用IFRAME做過同樣的
24、事情”。實(shí)際上,我們自己也曾用過這種方法。從前所做的一般稱為遠(yuǎn)程腳本(remote scripting),很多人認(rèn)為這只是一種修修補(bǔ)補(bǔ)。不過,這確實(shí)提供了一種能避免頁面刷新的機(jī)制。1.5.1 遠(yuǎn)程腳本概述基本說來,遠(yuǎn)程腳本是一種遠(yuǎn)程過程調(diào)用。可以像一個(gè)正常的Web應(yīng)用一樣與服務(wù)器交互,但是不用刷新整個(gè)頁面。與Ajax類似,可以調(diào)用任何服務(wù)器端技術(shù)來接收請求、處理請求并返回一個(gè)有意義的結(jié)果。不光是服務(wù)器端有很多選擇,客戶端同樣有許多實(shí)現(xiàn)遠(yuǎn)程腳本的選擇??梢栽趹?yīng)用中嵌入一個(gè)Flash動(dòng)畫、一個(gè)Java applet,或者一個(gè)ActiveX組件。甚至可以使用XML-RPC,但是這種方法太過復(fù)雜,因此
25、除非你對這種技術(shù)確實(shí)很了解,否則這種方法不太合適。實(shí)現(xiàn)遠(yuǎn)程腳本的通常做法是將腳本與一個(gè)IFRAME(隱藏或不隱藏)結(jié)合,由服務(wù)器返回 JavaScript,然后再在瀏覽器中運(yùn)行這個(gè)JavaScript。Microsoft提供了自己的遠(yuǎn)程腳本解決方案,并聰明地稱之為Microsoft遠(yuǎn)程腳本(Microsoft Remote Scripting,MSRS)。采用這種方法,可以像調(diào)用本地腳本一樣調(diào)用服務(wù)器腳本。頁面中嵌入一個(gè)Java applet,以便與服務(wù)器通信,在一個(gè).asp頁面中放置服務(wù)器端腳本,并用一個(gè).htm文件管理客戶端的布局?jǐn)[放。在Netscape和Internet Explorer
26、 4.0及更高版本上都可以使用Microsoft的這種解決方案。可以同步調(diào)用,也可以異步調(diào)用。不過,這種解決方案需要Java,這意味著可能需要再安裝Java,而且還需要Internet Information Services(IIS),因此會(huì)限制服務(wù)器端的選擇。Brent Ashley為遠(yuǎn)程腳本創(chuàng)建了兩個(gè)免費(fèi)的跨平臺庫。 JSRS是一個(gè)客戶端JavaScript庫,充分利用了DHTML向服務(wù)器做遠(yuǎn)程調(diào)用。相當(dāng)多的操作系統(tǒng)和瀏覽器上都能使用JSRS。如果采用一些常用的流行服務(wù)器端實(shí)現(xiàn)(如 PHP、Python和Perl CGI),一般都能在你的網(wǎng)站上安裝并運(yùn)行JSRS。Ashley免費(fèi)提供了J
27、SRS,而且還可以從他的網(wǎng)站(如果你覺得JSRS太過笨重,Ashley還創(chuàng)建了RSLite,這個(gè)庫使用了cookie,僅限于發(fā)送少量的數(shù)據(jù),只能做簡單的調(diào)用,不過大多數(shù)瀏覽器都能提供支持。1.5.2 遠(yuǎn)程腳本的一個(gè)例子為了進(jìn)行比較,這里向你展示如何使用IFRAME來實(shí)現(xiàn)類Ajax的技術(shù)。這非常簡單,而且過去我們就用過這種方法(在XMLHttpRequest問世之前)。這個(gè)例子并沒有真正調(diào)用服務(wù)器,只是想讓你對如何使用IFRAME實(shí)現(xiàn)遠(yuǎn)程腳本有所認(rèn)識。這個(gè)例子包括兩個(gè)文件:iframe.html(見代碼清單2-2)和server.html(見代碼清單2-3)。server.html模擬了本應(yīng)從服
28、務(wù)器返回的響應(yīng)。代碼清單2-2 iframe.html文件<html><head><title>Example of remote scripting in an IFRAME</title></head><script type="text/javascript">function handleResponse() alert('this function is called from server.html');</script><body><h1>
29、;Remote Scripting with an IFRAME</h1><iframe id="beforexhr"name="beforexhr"style="width:0px; height:0px; border: 0px"src="blank.html"></iframe><a href="server.html" target="beforexhr">call the server</a></bo
30、dy></html>代碼清單2-3 server.html文件<html><head><title>the server</title></head><script type="text/javascript">window.parent.handleResponse();</script><body></body></html>圖2-2顯示了最初的頁面。運(yùn)行這個(gè)代碼生成的結(jié)果如圖2-3所示。圖見P311圖2-2 最初的頁面圖見P3121
31、圖2-3 調(diào)用“服務(wù)器”之后的頁面1.6 如何發(fā)送簡單的請求現(xiàn)在已經(jīng)準(zhǔn)備開始使用XMLHttpRequest對象了。我們剛剛討論了如何創(chuàng)建這個(gè)對象,下面來看如何向服務(wù)器發(fā)送請求,以及如何處理服務(wù)器的響應(yīng)。如果沒有以查詢參數(shù)或提交表單數(shù)據(jù)的形式向服務(wù)器發(fā)送任何信息,這就是最簡單的請求。實(shí)際中,往往都希望向服務(wù)器發(fā)送一些信息。使用XMLHttpRequest對象發(fā)送請求的基本步驟如下:1. 得到XMLHttpRequest對象實(shí)例的一個(gè)引用,為此,可以創(chuàng)建一個(gè)新的實(shí)例,也可以訪問包含有XMLHttpRequest實(shí)例的一個(gè)變量。2. 告訴XMLHttpRequest對象,哪個(gè)函數(shù)會(huì)處理XMLHtt
32、pRequest對象狀態(tài)的改變。為此要把對象的onreadystatechange屬性設(shè)置為指向一個(gè)JavaScript函數(shù)的指針。3. 指定請求的屬性。XMLHttpRequest對象的open()方法會(huì)指定將發(fā)出的請求。open()方法取3個(gè)參數(shù):一個(gè)是指示所用方法(通常是GET或POST)的串,另一個(gè)是表示目標(biāo)資源URL的串,還有一個(gè)Boolean值,指示請求是否是異步的。4. 將請求發(fā)送給服務(wù)器。XMLHttpRequest對象的send()方法會(huì)把請求傳送到指定的目標(biāo)資源。send()方法接受一個(gè)參數(shù),這通常是一個(gè)串或一個(gè)DOM對象。這個(gè)參數(shù)會(huì)作為請求體的一部分傳送到目標(biāo)URL。向s
33、end()方法提供參數(shù)時(shí),要確保open()中指定的方法是POST。如果沒有數(shù)據(jù)要作為請求體的一部分發(fā)送,則使用null。這些步驟很直觀:你需要XMLHttpRequest對象的一個(gè)實(shí)例,要告訴它如果狀態(tài)有變化該怎么做,還要告訴它向哪里發(fā)送請求,以及如何發(fā)送請求,最后還需要指導(dǎo)XMLHttpRequest傳送請求。不過,除非你對C或C+很了解,否則可能不明白函數(shù)指針(function pointer)是什么意思。函數(shù)指針與任何其他變量類似,只不過它指向的不是像串、數(shù)字、甚至對象實(shí)例之類的數(shù)據(jù),而指向一個(gè)函數(shù)。在JavaScript中,所有函數(shù)在內(nèi)存中都編有地址,可以使用函數(shù)名引用。這就提供了很
34、大的靈活性,可以把函數(shù)指針作為參數(shù)傳遞給其他函數(shù),或者在一個(gè)對象的屬性中存儲函數(shù)指針。對于XMLHttpRequest對象,onreadystatechange屬性就存儲了回調(diào)函數(shù)的指針。當(dāng)XMLHttpRequest對象的內(nèi)部狀態(tài)發(fā)生變化時(shí),就會(huì)調(diào)用這個(gè)回調(diào)函數(shù)。如果做了一個(gè)異步調(diào)用,發(fā)出請求后,腳本會(huì)立即繼續(xù)處理,在腳本繼續(xù)工作之前,不必等待請求結(jié)束。一旦發(fā)出了請求,對象的readyState屬性會(huì)經(jīng)過幾個(gè)變化。盡管針對每個(gè)狀態(tài)都可以做一些處理,不過你最感興趣的狀態(tài)可能是服務(wù)器響應(yīng)結(jié)束時(shí)的狀態(tài)。通過設(shè)置回調(diào)函數(shù),就可以有效地告訴XMLHttpRequest對象:“只要響應(yīng)到來,就調(diào)用這個(gè)函
35、數(shù)來處理響應(yīng)?!?.6.1 一個(gè)簡單的請求例子第一個(gè)例子很簡單。這是一個(gè)很小的HTML頁面,只有一個(gè)按鈕。點(diǎn)擊這個(gè)按鈕會(huì)初始化一個(gè)發(fā)至服務(wù)器的異步請求。服務(wù)器將發(fā)回一個(gè)簡單的靜態(tài)文本文件作為響應(yīng)。處理這個(gè)響應(yīng)時(shí),會(huì)在一個(gè)警告窗口中顯示該靜態(tài)文本文件的內(nèi)容。代碼清單2-4顯示了這個(gè)HTML頁面和相關(guān)的JavaScript。代碼清單2-4simpleRequest.html 頁面<!DOCTYPE html PUBLIC "-/W3C/DTD XHTML 1.0 Strict/EN""/TR/xhtml1/DTD/xhtml1-s
36、trict.dtd"><html xmlns="/1999/xhtml"><head><title>Simple XMLHttpRequest</title><script type="text/javascript">var xmlHttp;function createXMLHttpRequest() if (window.ActiveXObject) xmlHttp = new ActiveXObject("Microsoft.XM
37、LHTTP");else if (window.XMLHttpRequest) xmlHttp = new XMLHttpRequest();function startRequest() createXMLHttpRequest();xmlHttp.onreadystatechange = handleStateChange;xmlHttp.open("GET", "simpleResponse.xml", true);xmlHttp.send(null);function handleStateChange() if(xmlHttp.rea
38、dyState = 4) if(xmlHttp.status = 200) alert("The server replied with: " + xmlHttp.responseText);</script></head><body><form action="#"><input type="button" value="Start Basic Asynchronous Request"onclick="startRequest();"/&
39、gt;</form></body></html>服務(wù)器的響應(yīng)文件simpleResponse.xml只有一行文本。點(diǎn)擊HTML頁面上的按鈕會(huì)生成一個(gè)警告框,其中顯示simpleResponse.xml文件的內(nèi)容。在圖2-4中可以看到分別在Internet Explorer和Firefox中顯示服務(wù)器響應(yīng)的警告框。圖見P341圖2-4 第一個(gè)簡單的異步請求對服務(wù)器的請求是異步發(fā)送的,因此瀏覽器可以繼續(xù)響應(yīng)用戶輸入,并在后臺等待服務(wù)器的響應(yīng)。如果選擇同步操作,而且倘若服務(wù)器的響應(yīng)要花好幾秒才能到達(dá),瀏覽器就會(huì)表現(xiàn)得很遲鈍,在等待期間不能響應(yīng)用戶的輸入。這樣一來,
40、瀏覽器好像被凍住一樣,無法響應(yīng)用戶輸入,而異步做法可以避免這種情況,從而讓最終用戶有更好的體驗(yàn),盡管這種改善很細(xì)微,但確實(shí)很有意義。這樣用戶就能繼續(xù)工作,而且服務(wù)器會(huì)在后臺處理先前的請求。能與服務(wù)器通信而不打斷用戶的工作流,這樣就可以采用很多技術(shù)來改善用戶體驗(yàn)。例如,假設(shè)有一個(gè)驗(yàn)證用戶輸入的應(yīng)用。用戶在輸入表單上填寫各個(gè)域時(shí),瀏覽器可以定期地向服務(wù)器發(fā)送表單值來進(jìn)行驗(yàn)證,此時(shí)并不打斷用戶,他還可以繼續(xù)填寫余下的表單域。如果某個(gè)驗(yàn)證規(guī)則失敗,用戶會(huì)立即得到通知,而不必等表單真正發(fā)送到服務(wù)器進(jìn)行處理時(shí)才知道有錯(cuò)誤,這就能大大節(jié)省用戶的時(shí)間,也能減輕服務(wù)器上的負(fù)載壓力,因?yàn)椴槐卦诒韱翁峤徊怀晒r(shí)完全
41、重建表單的內(nèi)容。1.6.2 關(guān)于安全討論基于瀏覽器的技術(shù)時(shí),如果沒有提到安全,那么討論就是不完整的。XMLHttpRequest對象要受制于瀏覽器的安全“沙箱”。XMLHttpRequest對象請求的所有資源都必須與調(diào)用腳本在同一個(gè)域(domain)內(nèi)。這個(gè)安全限制使得XMLHttpRequest對象不能請求腳本所在域之外的資源。這個(gè)安全限制的強(qiáng)度如何因?yàn)g覽器而異(見圖2-5)。Internet Explorer會(huì)顯示一個(gè)警告,指出可能存在一個(gè)安全風(fēng)險(xiǎn),但是用戶可以選擇是否繼續(xù)發(fā)出請求。Firefox則會(huì)斷然停止請求,并在JavaScript控制臺顯示一個(gè)錯(cuò)誤消息。圖見P351圖2-5 對于可
42、能的安全威脅,Internet Explorer和Firefox有不同的響應(yīng)Firefox確實(shí)提供了一些JavaScript技巧,使得XMLHttpRequest也可以請求外部URL的資源。不過,由于這些技術(shù)針對特定的瀏覽器,最好不要用,而且要避免使用XMLHttpRequest訪問外部URL。1.7 DOM Level 3 加載和保存規(guī)范到目前為止,我們討論的解決方案都不是標(biāo)準(zhǔn)。盡管XMLHttpRequest得到了廣泛支持,但是你已經(jīng)看到了,創(chuàng)建XMLHttpRequest對象的過程會(huì)隨瀏覽器不同而有所差異。許多人錯(cuò)誤地認(rèn)為Ajax得到了W3C的支持,但實(shí)際上并非如此。W3C提出了一個(gè)新的
43、標(biāo)準(zhǔn),力圖解決這樣一些問題,這個(gè)標(biāo)準(zhǔn)的名字相當(dāng)長:DOM Level 3 加載和保存規(guī)范(DOM Level 3 Load and Save Specification)。這個(gè)規(guī)范設(shè)計(jì)為允許以一種獨(dú)立于平臺和語言的方式,用XML內(nèi)容修改DOM文檔的內(nèi)容。2004年4月提出了1.0版本,但到目前為止,還沒有哪個(gè)瀏覽器實(shí)現(xiàn)這個(gè)規(guī)范。什么時(shí)候“加載和保存”(Load and Save)規(guī)范能取代Ajax?誰也不知道。想想看有多少瀏覽器沒有完全支持現(xiàn)有的標(biāo)準(zhǔn),所以這很難說,但是隨著越來越多的網(wǎng)站和應(yīng)用利用了Ajax技術(shù),可能以后的版本會(huì)得到支持。不過,較早的DOM版本就花了很長時(shí)間才得到采納,所以你得
44、耐心一點(diǎn)。在一次訪談中,DOM Activity主席Philippe Le Hégaret稱,需要花“相當(dāng)長的時(shí)間”才能得到廣泛采納。DOM Level 3也得到了一些支持,Opera的 XMLHttpRequest實(shí)現(xiàn)就基于DOM Level 3,而且面向XML的Java API(Java API for XML Processing,JAXP)1.3版本也支持DOM Level 3。不過,從出現(xiàn)了相應(yīng)的W3C規(guī)范這一點(diǎn)來看,起碼可以表明Ajax技術(shù)的重要性。從1997年8月起,人們就一直在為解決瀏覽器之間的不兼容而努力,“加載和保存”規(guī)范則達(dá)到了極致。你可能注意到,標(biāo)題里寫的是“Level 3”,那么Level 1 和Level 2呢?Level 1在1998年10完成,為我們帶
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年企業(yè)官方勞動(dòng)合同崗位樣本
- 全方位殯葬服務(wù)全程合同
- 水電材料訂購合同2025年示范文本
- 2025年單位員工宿舍轉(zhuǎn)租協(xié)議
- 2025年度學(xué)校消防設(shè)備更新策劃終止合同協(xié)議樣本
- 2025年個(gè)體工商戶土地承包合同范文
- 2025年兒童收養(yǎng)協(xié)議書規(guī)范文本
- 2025年信息技術(shù)服務(wù)費(fèi)用合同協(xié)議書模板
- 2025年鄭州貨物運(yùn)輸從業(yè)資格考試答題軟件
- 2025年交易減讓合同模版
- 江蘇省2023年對口單招英語試卷及答案
- GB/T 35506-2017三氟乙酸乙酯(ETFA)
- GB/T 25784-20102,4,6-三硝基苯酚(苦味酸)
- GB/T 21114-2007耐火材料X射線熒光光譜化學(xué)分析熔鑄玻璃片法
- 特種設(shè)備安全監(jiān)察指令書填寫規(guī)范(特種設(shè)備安全法)參考范本
- 航空維修工程管理-第1章課件
- 《長方形的面積》-完整版課件
- 五年級上冊英語Module6Unit1Youcanplaybasketballwell外研社課件
- 工業(yè)企業(yè)現(xiàn)場監(jiān)測工況核查表
- 沉淀池及排水溝清理記錄表
- 玩具公司職位說明書匯編
評論
0/150
提交評論