前端之 XMLHttpRequest
XMLHttpRequest 和AJAX的愛(ài)恨情仇
AJAX 是 asynchronous javascript and XML 的簡(jiǎn)寫(xiě),中文翻譯是異步的 javascript 和 XML,這一技術(shù)能夠向服務(wù)器請(qǐng)求額外的數(shù)據(jù)而無(wú)須卸載頁(yè)面,會(huì)帶來(lái)更好的用戶體驗(yàn)。雖然名字中包含 XML ,但 AJAX 通信與數(shù)據(jù)格式無(wú)關(guān)
AJAX 包括以下幾步驟:1、創(chuàng)建 AJAX 對(duì)象;2、發(fā)出 HTTP 請(qǐng)求;3、接收服務(wù)器傳回的數(shù)據(jù);4、更新網(wǎng)頁(yè)數(shù)據(jù)
概括起來(lái),就是一句話,AJAX 通過(guò)原生的 XMLHttpRequest 對(duì)象發(fā)出 HTTP 請(qǐng)求,得到服務(wù)器返回的數(shù)據(jù)后,再進(jìn)行處理
AJAX 技術(shù)的核心是 XMLHttpReques t對(duì)象(簡(jiǎn)稱XHR),這是由微軟首先引入的一個(gè)特性,其他瀏覽器提供商后來(lái)都提供了相同的實(shí)現(xiàn)。XHR 為向服務(wù)器發(fā)送請(qǐng)求和解析服務(wù)器響應(yīng)提供了流暢的接口,能夠以異步方式從服務(wù)器取得更多信息,意味著用戶單擊后,可以不必刷新頁(yè)面也能取得新數(shù)據(jù)
XMLHttpRequest 對(duì)象是當(dāng)今所有 AJAX 和 Web 2.0 應(yīng)用程序的技術(shù)基礎(chǔ)。盡管軟件經(jīng)銷(xiāo)商和開(kāi)源社團(tuán)現(xiàn)在都在提供各種 AJAX 框架以進(jìn)一步簡(jiǎn)化 XMLHttpRequest 對(duì)象的使用;但是,我們?nèi)匀缓苡斜匾斫膺@個(gè)對(duì)象的詳細(xì)工作機(jī)制。
IE5 是第一款引入 XHR 對(duì)象的瀏覽器。在 IE5 中,XHR 對(duì)象是通過(guò) MSXML 庫(kù)中的一個(gè) ActiveX 對(duì)象實(shí)現(xiàn)的,而 IE7+ 及其他標(biāo)準(zhǔn)瀏覽器都支持原生的XHR對(duì)象
一、 引言
AJAX 利用一個(gè)構(gòu)建到所有現(xiàn)代瀏覽器內(nèi)部的對(duì)象 XMLHttpRequest 來(lái)實(shí)現(xiàn)發(fā)送和接收 HTTP 請(qǐng)求與響應(yīng)信息。一個(gè)經(jīng)由XMLHttpRequest 對(duì)象發(fā)送的 HTTP 請(qǐng)求并不要求頁(yè)面中擁有或回寄一個(gè)<form>元素。AJAX 中的"A"代表了"異步",這意味著XMLHttpRequest 對(duì)象的 send() 方法可以立即返回,從而讓 Web 頁(yè)面上的其它 HTML/JavaScript 繼續(xù)其瀏覽器端處理而由服務(wù)器處理HTTP 請(qǐng)求并發(fā)送響應(yīng)。盡管缺省情況下請(qǐng)求是異步進(jìn)行的,但是,你可以選擇發(fā)送同步請(qǐng)求,這將會(huì)暫停其它Web頁(yè)面的處理,直到該頁(yè)面接收到服務(wù)器的響應(yīng)為止。
微軟在其 Internet Explorer(IE) 5 中作為一個(gè) ActiveX 對(duì)象形式引入了 XMLHttpRequest 對(duì)象。其他的認(rèn)識(shí)到這一對(duì)象重要性的瀏覽器制造商也都紛紛在他們的瀏覽器內(nèi)實(shí)現(xiàn)了 XMLHttpRequest 對(duì)象,但是作為一個(gè)本地 JavaScript 對(duì)象而不是作為一個(gè) ActiveX 對(duì)象實(shí)現(xiàn)。而如今,在認(rèn)識(shí)到實(shí)現(xiàn)這一類(lèi)型的價(jià)值及安全性特征之后,微軟已經(jīng)在其 IE 7中把 XMLHttpRequest 實(shí)現(xiàn)為一個(gè)窗口對(duì)象屬性。幸運(yùn)的是,盡管其實(shí)現(xiàn)(因而也影響到調(diào)用方式)細(xì)節(jié)不同,但是,所有的瀏覽器實(shí)現(xiàn)都具有類(lèi)似的功能,并且實(shí)質(zhì)上是相同方法。目前,W3C組織正在努力進(jìn)行 XMLHttpRequest 對(duì)象的標(biāo)準(zhǔn)化,并且已經(jīng)發(fā)行了有關(guān)該W3C規(guī)范的一個(gè)草案。
二、 XMLHttpRequest對(duì)象的屬性和事件
前端在接收到響應(yīng)后,第一步是檢查status屬性,以確定響應(yīng)已經(jīng)成功返回。一般來(lái)說(shuō),可以將HTTP狀態(tài)碼為200作為成功的標(biāo)志。此時(shí),responseText屬性的內(nèi)容已經(jīng)就緒,而且在內(nèi)容類(lèi)型正確的情況下,responseXML也可以訪問(wèn)了。此外,狀態(tài)碼為304表示請(qǐng)求的資源并沒(méi)有被修改,可以直接使用瀏覽器中緩存的版本;當(dāng)然,也意味著響應(yīng)是有效的
無(wú)論內(nèi)容類(lèi)型是什么,響應(yīng)主體的內(nèi)容都會(huì)保存到responseText屬性中,而對(duì)于非XML數(shù)據(jù)而言,responseXML屬性的值將為null
XMLHttpRequest對(duì)象暴露各種屬性、方法和事件以便于腳本處理和控制HTTP請(qǐng)求與響應(yīng)。
-
readyState屬性
當(dāng)XMLHttpRequest對(duì)象把一個(gè)HTTP請(qǐng)求發(fā)送到服務(wù)器時(shí)將經(jīng)歷若干種狀態(tài):一直等待直到請(qǐng)求被處理;然后,它才接收一個(gè)響應(yīng)。這樣以來(lái),腳本才正確響應(yīng)各種狀態(tài)-XMLHttpRequest對(duì)象暴露一個(gè)描述對(duì)象的當(dāng)前狀態(tài)的readyState屬性。
ReadyState取值 描述 0? 描述一種"未初始化"狀態(tài);此時(shí),已經(jīng)創(chuàng)建一個(gè)XMLHttpRequest對(duì)象,但是還沒(méi)有初始化。 1? 描述一種"發(fā)送"狀態(tài);此時(shí),代碼已經(jīng)調(diào)用了XMLHttpRequest open()方法并且XMLHttpRequest已經(jīng)準(zhǔn)備好把一個(gè)請(qǐng)求發(fā)送到服務(wù)器。 2? 描述一種"發(fā)送"狀態(tài);此時(shí),已經(jīng)通過(guò)send()方法把一個(gè)請(qǐng)求發(fā)送到服務(wù)器端,但是還沒(méi)有收到一個(gè)響應(yīng)。 3? 描述一種"正在接收"狀態(tài);此時(shí),已經(jīng)接收到HTTP響應(yīng)頭部信息,但是消息體部分還沒(méi)有完全接收結(jié)束。 4? 描述一種"已加載"狀態(tài);此時(shí),響應(yīng)已經(jīng)被完全接收。-
onreadystatechange事件
無(wú)論readyState值何時(shí)發(fā)生改變,XMLHttpRequest對(duì)象都會(huì)激發(fā)一個(gè)readystatechange事件。其中,onreadystatechange屬性接收一個(gè)EventListener值-向該方法指示無(wú)論readyState值何時(shí)發(fā)生改變,該對(duì)象都將激活。
-
responseText屬性
字符串,只讀,請(qǐng)求不成功或者數(shù)據(jù)不完整,該屬性為null。如果返回的是JSON格式的數(shù)據(jù),就可以調(diào)用responseText屬性
這個(gè)responseText屬性包含客戶端接收到的HTTP響應(yīng)的文本內(nèi)容。當(dāng)readyState值為0、1或2時(shí),responseText包含一個(gè)空字符串。當(dāng)readyState值為3(正在接收)時(shí),響應(yīng)中包含客戶端還未完成的響應(yīng)信息。當(dāng)readyState為4(已加載)時(shí),該responseText包含完整的響應(yīng)信息。
-
responseXML屬性
此responseXML屬性用于當(dāng)接收到完整的HTTP響應(yīng)時(shí)(readyState為4)描述XML響應(yīng);此時(shí),Content-Type頭部指定MIME(媒體)類(lèi)型為text/xml,application/xml或以+xml結(jié)尾。如果Content-Type頭部并不包含這些媒體類(lèi)型之一,那么responseXML的值為null。無(wú)論何時(shí),只要readyState值不為4,那么該responseXML的值也為null。
其實(shí),這個(gè)responseXML屬性值是一個(gè)文檔接口類(lèi)型的對(duì)象,用來(lái)描述被分析的文檔。如果文檔不能被分析(例如,如果文檔不是良構(gòu)的或不支持文檔相應(yīng)的字符編碼),那么responseXML的值將為null。
-
status屬性
只讀屬性,HTTP狀態(tài)碼,是一個(gè)三位數(shù)的整數(shù)。其類(lèi)型為short。而且,僅當(dāng)readyState值為3(正在接收中)或4(已加載)時(shí),這個(gè)status屬性才可用。當(dāng)readyState的值小于3時(shí)試圖存取status的值將引發(fā)一個(gè)異常。
200,ok,響應(yīng)成功。 301,Moved Permanently,永久移動(dòng)。 302, Move temporarily,暫時(shí)移動(dòng) 304, Not Modified,未修改 307, Temporary Redirect,暫時(shí)重定向 401, Unauthorized,未授權(quán) 403, Forbidden,禁止訪問(wèn) 404, Not Found,未發(fā)現(xiàn)請(qǐng)求資源 500, Internal Server Error,服務(wù)器發(fā)生錯(cuò)誤只有 2xx和304表示服務(wù)器正常。-
statusText屬性
只讀屬性,一個(gè)字符串,表示服務(wù)器的狀態(tài),是一個(gè)完整信息,如 “200 OK”。描述了HTTP狀態(tài)代碼文本;并且僅當(dāng)readyState值為3或4才可用。當(dāng)readyState為其它值時(shí)試圖存取statusText屬性將引發(fā)一個(gè)異常。
-
responseType屬性
類(lèi)型可以是ArrayBuffer(內(nèi)存緩沖區(qū)?不太理解)、Bold(前端的一個(gè)對(duì)象)、Documnet(Document對(duì)象即XML、html文檔或html片段)、JSON(JS對(duì)象)、text(字符串)。
xhr.responseType="json";responseType 設(shè)置為 json,支持json的瀏覽器,主流瀏覽器都支持,會(huì)自動(dòng)調(diào)用JSON.parese()方法,將JSON解析為JS對(duì)象,就是說(shuō) 從xhr.response(不是xhr.responseText屬性)屬性得到的不是文本,是JS對(duì)象。
三、 XMLHttpRequest對(duì)象的方法
-
abort()方法
你可以使用這個(gè)abort()方法來(lái)暫停與一個(gè)XMLHttpRequest對(duì)象相聯(lián)系的HTTP請(qǐng)求,從而把該對(duì)象復(fù)位到未初始化狀態(tài)。
-
open()方法
調(diào)用open(DOMString method,DOMString uri,boolean async,DOMString username,DOMString password)方法初始化一個(gè)XMLHttpRequest對(duì)象。例如
xhr.open("get","example.php", false);- 第一個(gè)參數(shù)用于指定發(fā)送請(qǐng)求的方式,這個(gè)字符串,不區(qū)分大小寫(xiě),但通常使用大寫(xiě)字母。
- 第二個(gè)參數(shù)是URL,該URL相對(duì)于執(zhí)行代碼的當(dāng)前頁(yè)面,且只能向同一個(gè)域中使用相同端口和協(xié)議的URL發(fā)送請(qǐng)求。如果URL與啟動(dòng)請(qǐng)求的頁(yè)面有任何差別,都會(huì)引發(fā)安全錯(cuò)誤。借助于window.document.baseURI屬性,該uri被解析為一個(gè)絕對(duì)的URI-換句話說(shuō),你可以使用相對(duì)的URI-它將使用與瀏覽器解析相對(duì)的URI一樣的方式被解析。
- 第三個(gè)參數(shù)async參數(shù)指定是否請(qǐng)求是異步的-缺省值為true。為了發(fā)送一個(gè)同步請(qǐng)求,需要把這個(gè)參數(shù)設(shè)置為false。
- 對(duì)于要求認(rèn)證的服務(wù)器,你可以提供可選的用戶名和口令參數(shù)。在調(diào)用open()方法后,XMLHttpRequest對(duì)象把它的readyState屬性設(shè)置為1(打開(kāi))并且把responseText、responseXML、status和statusText屬性復(fù)位到它們的初始值。另外,它還復(fù)位請(qǐng)求頭部。注意,如果你調(diào)用open()方法并且此時(shí)readyState為4,則XMLHttpRequest對(duì)象將復(fù)位這些值。
在通過(guò)調(diào)用open()方法準(zhǔn)備好一個(gè)請(qǐng)求之后,你需要把該請(qǐng)求發(fā)送到服務(wù)器。僅當(dāng)readyState值為1時(shí),你才可以調(diào)用send()方法;否則的話,XMLHttpRequest對(duì)象將引發(fā)一個(gè)異常。該請(qǐng)求被使用提供給open()方法的參數(shù)發(fā)送到服務(wù)器。當(dāng)async參數(shù)為true時(shí),send()方法立即返回,從而允許其它客戶端腳本處理繼續(xù)。在調(diào)用send()方法后,XMLHttpRequest對(duì)象把readyState的值設(shè)置為2(發(fā)送)。當(dāng)服務(wù)器響應(yīng)時(shí),在接收消息體之前,如果存在任何消息體的話,XMLHttpRequest對(duì)象將把readyState設(shè)置為3(正在接收中)。當(dāng)請(qǐng)求完成加載時(shí),它把readyState設(shè)置為4(已加載)。對(duì)于一個(gè)HEAD類(lèi)型的請(qǐng)求,它將在把readyState值設(shè)置為3后再立即把它設(shè)置為4。
-
send()方法
send()方法接收一個(gè)參數(shù),即要作為請(qǐng)求主體發(fā)送的數(shù)據(jù)。調(diào)用send()方法后,請(qǐng)求被分派到服務(wù)器
如果是GET方法,send()方法無(wú)參數(shù),或參數(shù)為null;
如果是POST方法,send()方法的參數(shù)為要發(fā)送的數(shù)據(jù)。對(duì)于發(fā)送數(shù)據(jù)為其它的數(shù)據(jù)類(lèi)型,在調(diào)用send()方法之前,應(yīng)該使用setRequestHeader()方法(見(jiàn)后面的解釋)先設(shè)置Content-Type頭部。如果在send(data)方法中的data參數(shù)的類(lèi)型為DOMString,那么,數(shù)據(jù)將被編碼為UTF-8。如果數(shù)據(jù)是Document類(lèi)型,那么將使用由data.xmlEncoding指定的編碼串行化該數(shù)據(jù)。
在POST方法中,向服務(wù)器提交的表單數(shù)據(jù)傳入send()中,序列化和轉(zhuǎn)碼處理,鍵值對(duì)用&連接,如 "name=jack&age=20",且在send()調(diào)用前,需要設(shè)置MIME類(lèi)型:xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
setRequestHeader()方法
該setRequestHeader(DOMString header,DOMString value)方法用來(lái)設(shè)置請(qǐng)求的頭部信息。當(dāng)readyState值為1時(shí),你可以在調(diào)用open()方法后調(diào)用這個(gè)方法;否則,你將得到一個(gè)異常。
-
getResponseHeader()方法
getResponseHeader(DOMString header,value)方法用于檢索響應(yīng)的頭部值。僅當(dāng)readyState值是3或4(換句話說(shuō),在響應(yīng)頭部可用以后)時(shí),才可以調(diào)用這個(gè)方法;否則,該方法返回一個(gè)空字符串。
-
getAllResponseHeaders()方法
該getAllResponseHeaders()方法以一個(gè)字符串形式返回所有的響應(yīng)頭部(每一個(gè)頭部占單獨(dú)的一行)。如果readyState的值不是3或4,則該方法返回null。
四、 發(fā)送請(qǐng)求
在AJAX中,許多使用XMLHttpRequest的請(qǐng)求都是從一個(gè)HTML事件(例如一個(gè)調(diào)用JavaScript函數(shù)的按鈕點(diǎn)擊(onclick)或一個(gè)按鍵(onkeypress))中被初始化的。AJAX支持包括表單校驗(yàn)在內(nèi)的各種應(yīng)用程序。有時(shí),在填充表單的其它內(nèi)容之前要求校驗(yàn)一個(gè)唯一的表單域。例如要求使用一個(gè)唯一的UserID來(lái)注冊(cè)表單。如果不是使用AJAX技術(shù)來(lái)校驗(yàn)這個(gè)UserID域,那么整個(gè)表單都必須被填充和提交。如果該UserID不是有效的,這個(gè)表單必須被重新提交。例如,一個(gè)相應(yīng)于一個(gè)要求必須在服務(wù)器端進(jìn)行校驗(yàn)的Catalog ID的表單域可能按下列形式指定:? ?
<form name="validationForm" action="validateForm" method="post">? <table>?<tr><td>Catalog Id:</td>?<td>?<input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()">?</td>?<td><div id="validationMessage"></div></td>?</tr>? </table></form>前面的HTML使用validationMessage div來(lái)顯示相應(yīng)于這個(gè)輸入域Catalog Id的一個(gè)校驗(yàn)消息。onkeyup事件調(diào)用一個(gè)JavaScript sendRequest()函數(shù)。這個(gè)sendRequest()函數(shù)創(chuàng)建一個(gè)XMLHttpRequest對(duì)象。創(chuàng)建一個(gè)XMLHttpRequest對(duì)象的過(guò)程因?yàn)g覽器實(shí)現(xiàn)的不同而有所區(qū)別。如果瀏覽器支持XMLHttpRequest對(duì)象作為一個(gè)窗口屬性(所有普通的瀏覽器都是這樣的,除了IE 5和IE 6之外),那么,代碼可以調(diào)用XMLHttpRequest的構(gòu)造器。如果瀏覽器把XMLHttpRequest對(duì)象實(shí)現(xiàn)為一個(gè)ActiveXObject對(duì)象(就象在IE 5和IE 6中一樣),那么,代碼可以使用ActiveXObject的構(gòu)造器。下面的函數(shù)將調(diào)用一個(gè)init()函數(shù),它負(fù)責(zé)檢查并決定要使用的適當(dāng)?shù)膭?chuàng)建方法-在創(chuàng)建和返回對(duì)象之前。
<script type="text/javascript">? function sendRequest(){?var xmlHttpReq=init();?function init(){?if (window.XMLHttpRequest) {?return new XMLHttpRequest();?}else if (window.ActiveXObject) {?return new ActiveXObject("Microsoft.XMLHTTP");?}} } </script>??接下來(lái),你需要使用Open()方法初始化XMLHttpRequest對(duì)象-指定HTTP方法和要使用的服務(wù)器URL。
var catalogId=encodeURIComponent(document.getElementById("catalogId").value); xmlHttpReq.open("GET", "validateForm?catalogId=" + catalogId, true);默認(rèn)情況下,使用XMLHttpRequest發(fā)送的HTTP請(qǐng)求是異步進(jìn)行的,但是你可以顯式地把a(bǔ)sync參數(shù)設(shè)置為true,如上面所展示的。
在這種情況下,對(duì)URL validateForm的調(diào)用將激活服務(wù)器端的一個(gè)servlet,但是你應(yīng)該能夠注意到服務(wù)器端技術(shù)不是根本性的;實(shí)際上,該URL可能是一個(gè)ASP,ASP.NET或PHP頁(yè)面或一個(gè)Web服務(wù)-這無(wú)關(guān)緊要,只要該頁(yè)面能夠返回一個(gè)響應(yīng)-指示CatalogID值是否是有效的-即可。因?yàn)槟阍谧饕粋€(gè)異步調(diào)用,所以你需要注冊(cè)一個(gè)XMLHttpRequest對(duì)象將調(diào)用的回調(diào)事件處理器-當(dāng)它的readyState值改變時(shí)調(diào)用。記住,readyState值的改變將會(huì)激發(fā)一個(gè)readystatechange事件。你可以使用onreadystatechange屬性來(lái)注冊(cè)該回調(diào)事件處理器。
xmlHttpReq.onreadystatechange=processRequest;
然后,我們需要使用send()方法發(fā)送該請(qǐng)求。因?yàn)檫@個(gè)請(qǐng)求使用的是HTTP GET方法,所以,你可以在不指定參數(shù)或使用null參數(shù)的情況下調(diào)用send()方法。
xmlHttpReq.send(null);
五、 處理請(qǐng)求
在這個(gè)示例中,因?yàn)镠TTP方法是GET,所以在服務(wù)器端的接收servlet將調(diào)用一個(gè)doGet()方法,該方法將檢索在URL中指定的catalogId參數(shù)值,并且從一個(gè)數(shù)據(jù)庫(kù)中檢查它的有效性。
本文示例中的這個(gè)servlet需要構(gòu)造一個(gè)發(fā)送到客戶端的響應(yīng);而且,這個(gè)示例返回的是XML類(lèi)型,因此,它把響應(yīng)的HTTP內(nèi)容類(lèi)型設(shè)置為text/xml并且把Cache-Control頭部設(shè)置為no-cache。設(shè)置Cache-Control頭部可以阻止瀏覽器簡(jiǎn)單地從緩存中重載頁(yè)面。
// java 代碼,我不是很懂。。 public void doGet(HttpServletRequest request,?? HttpServletResponse response)? throws ServletException, IOException {?...?...?response.setContentType("text/xml");?response.setHeader("Cache-Control", "no-cache");? }??來(lái)自于服務(wù)器端的響應(yīng)是一個(gè)XML DOM對(duì)象,此對(duì)象將創(chuàng)建一個(gè)XML字符串-其中包含要在客戶端進(jìn)行處理的指令。另外,該XML字符串必須有一個(gè)根元素。
out.println("<catalogId>valid</catalogId>");
【注意】XMLHttpRequest對(duì)象的設(shè)計(jì)目的是為了處理由普通文本或XML組成的響應(yīng);但是,一個(gè)響應(yīng)也可能是另外一種類(lèi)型,如果用戶代理(UA)支持這種內(nèi)容類(lèi)型的話。
當(dāng)請(qǐng)求狀態(tài)改變時(shí),XMLHttpRequest對(duì)象調(diào)用使用onreadystatechange注冊(cè)的事件處理器。因此,在處理該響應(yīng)之前,你的事件處理器應(yīng)該首先檢查readyState的值和HTTP狀態(tài)。當(dāng)請(qǐng)求完成加載(readyState值為4)并且響應(yīng)已經(jīng)完成(HTTP狀態(tài)為"OK")時(shí),你就可以調(diào)用一個(gè)JavaScript函數(shù)來(lái)處理該響應(yīng)內(nèi)容。下列腳本負(fù)責(zé)在響應(yīng)完成時(shí)檢查相應(yīng)的值并調(diào)用一個(gè)processResponse()方法。
function processRequest(){if(xmlHttpReq.readyState==4){if(xmlHttpReq.status==200){processResponse();}} }該processResponse()方法使用XMLHttpRequest對(duì)象的responseXML和responseText屬性來(lái)檢索HTTP響應(yīng)。如上面所解釋的,僅當(dāng)在響應(yīng)的媒體類(lèi)型是text/xml,application/xml或以+xml結(jié)尾時(shí),這個(gè)responseXML才可用。這個(gè)responseText屬性將以普通文本形式返回響應(yīng)。對(duì)于一個(gè)XML響應(yīng),你將按如下方式檢索內(nèi)容:
var msg=xmlHttpReq.responseXML;
借助于存儲(chǔ)在msg變量中的XML,你可以使用DOM方法getElementsByTagName()來(lái)檢索該元素的值:
var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue;
最后,通過(guò)更新Web頁(yè)面的validationMessage div中的HTML內(nèi)容并借助于innerHTML屬性,你可以測(cè)試該元素值以創(chuàng)建一個(gè)要顯示的消息:
if(catalogId=="valid"){var validationMessage = document.getElementById("validationMessage");validationMessage.innerHTML = "Catalog Id is Valid"; } else {var validationMessage = document.getElementById("validationMessage");validationMessage.innerHTML = "Catalog Id is not Valid"; }六、兼容性問(wèn)題
window.ActiveXObject 對(duì)象
創(chuàng)建XMLHttpRequest 對(duì)象,必須考慮到瀏覽器兼容問(wèn)題,有時(shí)可以利用判斷瀏覽器是否支持ActiveX控件,如果瀏覽器支持ActiveX控件可以:
- var xml=new ActiveXObject("Microsoft.XMLHTTP");創(chuàng)建XMLHttpRequest 對(duì)象(IE7以前的版本中);
- var xml=new ActiveXObject("Msxml2.XMLHTTP");在較新的IE版本中創(chuàng)建XMLHttpRequest對(duì)象;
- var xml=new XMLHttpRequest();而在IE7以后及非IE瀏覽器中創(chuàng)建XMLHttpRequest對(duì)象。
首先我們來(lái)看看怎么來(lái)聲明(使用)它,在使用XMLHTTPRequest對(duì)象發(fā)送請(qǐng)求和處理響應(yīng)之前,我們必須要用javascript創(chuàng)建一個(gè)XMLHTTPRequest對(duì)象。(IE把XMLHTTPRequest實(shí)現(xiàn)為一個(gè)ActiveX對(duì)象,其他的瀏覽器[如Firefox/Safari/Opear]則把它實(shí)現(xiàn)為一個(gè)本地的javascript對(duì)象)。下面我們就來(lái)看看具體怎么運(yùn)用javascript來(lái)創(chuàng)建它吧:
<script language="javascript" type="text/javascript"> var xmlhttp; // 創(chuàng)建XMLHTTPRequest對(duì)象 function createXMLHTTPRequest(){if(window.ActiveXObject){ // 判斷是否支持ActiveX控件xmlhttp = new ActiveObject("Microsoft.XMLHTTP"); // 通過(guò)實(shí)例化ActiveXObject的一個(gè)新實(shí)例來(lái)創(chuàng)建XMLHTTPRequest對(duì)象}else if(window.XMLHTTPRequest){ // 判斷是否把XMLHTTPRequest實(shí)現(xiàn)為一個(gè)本地javascript對(duì)象xmlhttp = new XMLHTTPRequest(); // 創(chuàng)建XMLHTTPRequest的一個(gè)實(shí)例(本地javascript對(duì)象)} } </script>js用來(lái)區(qū)別IE與其他瀏覽器及IE6-8之間的方法。
- document.all
- !!window.ActiveXObject;
使用方法如下:
if (document.all){alert(”IE瀏覽器”); }else{alert(”非IE瀏覽器”); } if (!!window.ActiveXObject){alert(”IE瀏覽器”); }else{alert(”非IE瀏覽器”); }區(qū)別IE6、IE7、IE8之間的方法:
var isIE=!!window.ActiveXObject; var isIE6=isIE&&!window.XMLHttpRequest; var isIE8=isIE&&!!document.documentMode; var isIE7=isIE&&!isIE6&&!isIE8; if (isIE){if (isIE6){alert(”ie6″);}else if (isIE8){alert(”ie8″);}else if (isIE7){alert(”ie7″);} }據(jù)說(shuō)火狐以后也會(huì)加入document.all這個(gè)方法,所以建議使用第二種方法,應(yīng)該會(huì)安全一些。
七、 小結(jié)
上面就是XMLHttpRequest對(duì)象使用的所有細(xì)節(jié)實(shí)現(xiàn)。通過(guò)不必把Web頁(yè)面寄送到服務(wù)器而實(shí)現(xiàn)數(shù)據(jù)傳送,XMLHttpRequest對(duì)象為客戶端與服務(wù)器之間提供了一種動(dòng)態(tài)的交互能力。你可以使用JavaScript啟動(dòng)一個(gè)請(qǐng)求并處理相應(yīng)的返回值,然后使用瀏覽器的DOM方法更新頁(yè)面中的數(shù)據(jù)。
附:簡(jiǎn)單的示例代碼
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">? <html xmlns="http://www.w3.org/1999/xhtml">? <head runat="server">?<meta http-equiv="Content-Type" content="text/html;charset=gb2312" />?<title>示例</title>?<script src="Ajax.js"></script>? </head>? <body>???? <a href="#" onclick="ajaxReader('data5.xml'); return false"> 查看</a>? <div id="dataArea">? </div>????????????? </body>? </html>? script:? // JScript File? function? ajaxReader(file)?{//定義xmlobj對(duì)象?var xmlObj=null;?if(window.XMLHttpRequest)? // 用 XMLHttpRequest 方式{xmlObj=new XMLHttpRequest();?}else if(window.ActiveXObject)? // 用 ActiveXObject 方式{xmlObj=new ActiveXObject("Microsoft.XMLHTTP");?}else?{return;?}// 第一種方式xmlObj.onreadystatechange=function(){ // 值發(fā)生變化時(shí)觸發(fā)if(xmlObj.readyState==4)?{ // 判斷processXML(xmlObj.responseXML);??}}?xmlObj.open('GET',file,true);? // 發(fā)送請(qǐng)求xmlObj.send('');? // send 發(fā)送 <!--// 第二種方式,下載docx// IE 版本xmlObj.open('GET',url,true);xmlObj.responseType = 'blob'xmlObj.setRequestHeader("Authorization", 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')//post請(qǐng)求一定要添加請(qǐng)求頭才行不然會(huì)報(bào)錯(cuò)if(model.type=='post'){xhr.setRequestHeader("Content-type","application/json");}xmlObj.onload = function(){if (this.status==200){var ret_data = this.response // this.response也就是請(qǐng)求的返回就是Blob對(duì)象var blob = new Blob([res.data.fileData],{type: 'application/json;charset=utf-8'}); //application/vnd.openxmlformats-officedocument.wordprocessingml.document這里表示doc類(lèi)型womdow.navigator.msSaveBlob(blob,data['file_name'])}xmlObj.send('');? }// 谷歌瀏覽器 創(chuàng)建a標(biāo)簽 添加download屬性下載var downloadElement = document.createElement('a');downloadElement.href = href;downloadElement.target = '_blank';downloadElement.download = 'model.json'; //下載后文件名document.body.appendChild(downloadElement);downloadElement.click(); //點(diǎn)擊下載document.body.removeChild(downloadElement); //下載完成移除元素window.URL.revokeObjectURL(href); //釋放掉blob對(duì)象-->}? function processXML(obj)? {var dataArray=obj.getElementsByTagName('pets')[0].childNodes;var dataArrayLength=dataArray.length;var insertData='<table>';insertData +='<tr><th>Pet5</th><th>Tasks</th></tr>';?for(var i=0;i<dataArrayLength;i++)?{?if(dataArray[i].tagName)?{?insertData+='<tr>';?????insertData +='<td>'+dataArray[i].tagName+'</td>';?insertData +="<td>"+dataArray[i].getAttribute('tasks')+'</td>';?insertData+='</tr>';????}?}insertData +=+'</table>';?document.getElementById('dataArea4').innerHTML =insertData;? }總結(jié)
以上是生活随笔為你收集整理的前端之 XMLHttpRequest的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 百度金融与农业银行战略合作,AI +金融
- 下一篇: vba 抓取php网页,用VBA操作网页