[转]WEB2.0中AJAX应用的详细探讨
生活随笔
收集整理的這篇文章主要介紹了
[转]WEB2.0中AJAX应用的详细探讨
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
最近互聯(lián)網(wǎng)上比較火熱的話題當(dāng)然是關(guān)于WEB2.0的應(yīng)用,其中AJAX又是WEB2.0的核心之一。AJAX是Asynchronous JavaScript and XML 的縮寫。它并不是一門新的語言或技術(shù),它實(shí)際上是幾項(xiàng)技術(shù)按一定的方式組合在一在同共的協(xié)作中發(fā)揮各自的作用,它包括
使用XHTML和CSS標(biāo)準(zhǔn)化呈現(xiàn);
使用DOM實(shí)現(xiàn)動(dòng)態(tài)顯示和交互;
使用XML和XSLT進(jìn)行數(shù)據(jù)交換與處理;
使用XMLHttpRequest進(jìn)行異步數(shù)據(jù)讀取;
最后用JavaScript綁定和處理所有數(shù)據(jù);
Ajax的工作原理相當(dāng)于在用戶和服務(wù)器之間加了—個(gè)中間層,使用戶操作與服務(wù)器響應(yīng)異步化。這樣把以前的一些服務(wù)器負(fù)擔(dān)的工作轉(zhuǎn)嫁到客戶端,利于客戶端閑置的處理能力來處理,減輕服務(wù)器和帶寬的負(fù)擔(dān),從而達(dá)到節(jié)約ISP的空間及帶寬租用成本的目的。
我們以兩個(gè)驗(yàn)證通行證帳號(hào)是否存在的例子來講述AJAX在實(shí)際中的應(yīng)用:
(1)????用文本字符串的方式返回服務(wù)器的響應(yīng)來驗(yàn)證網(wǎng)易通行證帳號(hào)是否存在;
(2)????以XMLDocument對(duì)象方式返回響應(yīng)來驗(yàn)證金山通行證帳號(hào)是否存在;
首先,我們需要用JavaScript來創(chuàng)建XMLHttpRequest 類向服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求, XMLHttpRequest 類首先由Internet Explorer以ActiveX對(duì)象引入,被稱為XMLHTTP。 后來Mozilla﹑Netscape﹑Safari 和其他瀏覽器也提供了XMLHttpRequest類,不過它們創(chuàng)建XMLHttpRequest類的方法不同。
對(duì)于Internet Explorer瀏覽器,創(chuàng)建XMLHttpRequest 方法如下:
xmlhttp_request = new ActiveXObject("Msxml2.XMLHTTP.3.0"); //3.0或4.0, 5.0 xmlhttp_request = new ActiveXObject("Msxml2.XMLHTTP"); xmlhttp_request = new ActiveXObject("Microsoft.XMLHTTP");
由于在不同Internet Explorer瀏覽器中XMLHTTP版本可能不一致,為了更好的兼容不同版本的Internet Explorer瀏覽器,因此我們需要根據(jù)不同版本的Internet Explorer瀏覽器來創(chuàng)建XMLHttpRequest類,上面代碼就是根據(jù)不同的Internet Explorer瀏覽器創(chuàng)建XMLHttpRequest類的方法。
對(duì)于Mozilla﹑Netscape﹑Safari等瀏覽器,創(chuàng)建XMLHttpRequest 方法如下:
xmlhttp_request = new XMLHttpRequest();
如果服務(wù)器的響應(yīng)沒有XML mime-type header,某些Mozilla瀏覽器可能無法正常工作。 為了解決這個(gè)問題,如果服務(wù)器響應(yīng)的header不是text/xml,可以調(diào)用其它方法修改該header。
xmlhttp_request = new XMLHttpRequest(); xmlhttp_request.overrideMimeType('text/xml');
在實(shí)際應(yīng)用中,為了兼容多種不同版本的瀏覽器,一般將創(chuàng)建XMLHttpRequest類的方法寫成如下形式:
try{if( window.ActiveXObject ){for( var i = 5; i; i-- ){try{if( i == 2 ){ xmlhttp_request = new ActiveXObject( "Microsoft.XMLHTTP" ); }else{ xmlhttp_request = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" ); } xmlhttp_request.setRequestHeader("Content-Type","text/xml"); xmlhttp_request.setRequestHeader("Content-Type","gb2312"); break;}catch(e){ xmlhttp_request = false;}}}else if( window.XMLHttpRequest ){xmlhttp_request = new XMLHttpRequest();if (xmlhttp_request.overrideMimeType) {xmlhttp_request.overrideMimeType('text/xml');}}}catch(e){xmlhttp_request = false;}
在定義了如何處理響應(yīng)后,就要發(fā)送請(qǐng)求了??梢哉{(diào)用HTTP請(qǐng)求類的open()和send()方法,如下所示:
xmlhttp_request.open('GET', URL, true); xmlhttp_request.send(null);
open()的第一個(gè)參數(shù)是HTTP請(qǐng)求方式—GET,POST或任何服務(wù)器所支持的您想調(diào)用的方式。 按照HTTP規(guī)范,該參數(shù)要大寫;否則,某些瀏覽器(如Firefox)可能無法處理請(qǐng)求。
第二個(gè)參數(shù)是請(qǐng)求頁面的URL。
第三個(gè)參數(shù)設(shè)置請(qǐng)求是否為異步模式。如果是TRUE,JavaScript函數(shù)將繼續(xù)執(zhí)行,而不等待服務(wù)器響應(yīng)。這就是"AJAX"中的"A"。
用JavaScript來創(chuàng)建XMLHttpRequest 類向服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求后,接下來要決定當(dāng)收到服務(wù)器的響應(yīng)后,需要做什么。這需要告訴HTTP請(qǐng)求對(duì)象用哪一個(gè)JavaScript函數(shù)處理這個(gè)響應(yīng)??梢詫?duì)象的onreadystatechange屬性設(shè)置為要使用的JavaScript的函數(shù)名,如下所示:
xmlhttp_request.onreadystatechange =FunctionName;
FunctionName是用JavaScript創(chuàng)建的函數(shù)名,注意不要寫成FunctionName(),當(dāng)然我們也可以直接將JavaScript代碼創(chuàng)建在onreadystatechange之后,例如:
xmlhttp_request.onreadystatechange = function(){// JavaScript代碼段 };
在這個(gè)函數(shù)中。首先要檢查請(qǐng)求的狀態(tài)。只有當(dāng)一個(gè)完整的服務(wù)器響應(yīng)已經(jīng)收到了,函數(shù)才可以處理該響應(yīng)。XMLHttpRequest 提供了readyState屬性來對(duì)服務(wù)器響應(yīng)進(jìn)行判斷。
readyState的取值如下:
0 (未初始化)
1 (正在裝載)
2 (裝載完畢)
3 (交互中)
4 (完成)
所以只有當(dāng)readyState=4時(shí),一個(gè)完整的服務(wù)器響應(yīng)已經(jīng)收到了,函數(shù)才可以處理該響應(yīng)。具體代碼如下:
if (http_request.readyState == 4) {// 收到完整的服務(wù)器響應(yīng) } else {// 沒有收到完整的服務(wù)器響應(yīng) }
當(dāng)readyState=4時(shí),一個(gè)完整的服務(wù)器響應(yīng)已經(jīng)收到了,接著,函數(shù)會(huì)檢查HTTP服務(wù)器響應(yīng)的狀態(tài)值。完整的狀態(tài)取值可參見W3C文檔。當(dāng)HTTP服務(wù)器響應(yīng)的值為200時(shí),表示狀態(tài)正常。
在檢查完請(qǐng)求的狀態(tài)值和響應(yīng)的HTTP狀態(tài)值后,就可以處理從服務(wù)器得到的數(shù)據(jù)了。有兩種方式可以得到這些數(shù)據(jù):
(1)????以文本字符串的方式返回服務(wù)器的響應(yīng)
(2)????以XMLDocument對(duì)象方式返回響應(yīng)
實(shí)例一: 用文本字符串的方式返回服務(wù)器的響應(yīng)來驗(yàn)證網(wǎng)易通行證帳號(hào)是否存在
首先,我們登陸網(wǎng)易通行證注冊(cè)頁面,可以看到檢測(cè)用戶名是否存在是將用戶名提交給checkssn.jsp頁面進(jìn)行判斷,格式為:
reg.163.com/register/checkssn.jsp?username=用戶名
根據(jù)上面講到的方法,我們可以利用AJAX技術(shù)對(duì)網(wǎng)易通行證用戶名進(jìn)行檢測(cè):
第一步:新建一個(gè)基于Xhtml標(biāo)準(zhǔn)的網(wǎng)頁,在<head>區(qū)域插入Javascript函數(shù)如下:
<script type="text/javascript" language="javascript"> function getXMLRequester( ){var xmlhttp_request = false;try{if( window.ActiveXObject ){for( var i = 5; i; i-- ){try{if( i == 2 ){ xmlhttp_request = new ActiveXObject( "Microsoft.XMLHTTP" ); }else{ xmlhttp_request = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" ); xmlhttp_request.setRequestHeader("Content-Type","text/xml"); xmlhttp_request.setRequestHeader("Content-Type","gb2312");} break;}catch(e){ xmlhttp_request = false;}}}else if( window.XMLHttpRequest ){xmlhttp_request = new XMLHttpRequest();if (xmlhttp_request.overrideMimeType) {xmlhttp_request.overrideMimeType('text/xml');}}}catch(e){xmlhttp_request = false;}return xmlhttp_request ; }function IDRequest(n) {//定義收到服務(wù)器的響應(yīng)后需要執(zhí)行的JavaScript函數(shù) url=n+document.getElementById('163id').value;//定義網(wǎng)址參數(shù)xmlhttp_request=getXMLRequester();//調(diào)用創(chuàng)建XMLHttpRequest的函數(shù)xmlhttp_request.onreadystatechange = doContents;//調(diào)用doContents函數(shù)xmlhttp_request.open('GET', url, true);xmlhttp_request.send(null);}function doContents() {if (xmlhttp_request.readyState == 4) {// 收到完整的服務(wù)器響應(yīng)if (xmlhttp_request.status == 200) {//HTTP服務(wù)器響應(yīng)的值OK document.getElementById('message').innerHTML = xmlhttp_request.responseText; //將服務(wù)器返回的字符串寫到頁面中ID為message的區(qū)域} else {alert(http_request.status);}}} </script>
在<body>區(qū)域建立一個(gè)文本框,id為163id
<input type="text" id="163id" onpropertychange="IDRequest('http://reg.163.com/register/checkssn.jsp?username=')" />
再建一個(gè)id為messsge的空白區(qū)域用來顯示返回字符串(也可以通過Javascript函數(shù)截取一部分字符串顯示):
<div id="message"></div>
這樣,一個(gè)基于AJAX技術(shù)的用戶名檢測(cè)頁面就做好了,不過這個(gè)頁面將返回服務(wù)器響應(yīng)生成頁面的所有字符串,當(dāng)然還可以對(duì)返回的字符串進(jìn)行一些操作,便于應(yīng)用到不同的需要當(dāng)中。
實(shí)例二: 以XMLDocument對(duì)象方式返回響應(yīng)來驗(yàn)證金山通行證帳號(hào)是否存在
在上面的例子中,當(dāng)服務(wù)器對(duì)HTTP請(qǐng)求的響應(yīng)被收到后,我們會(huì)調(diào)用請(qǐng)求對(duì)象的reponseText屬性。該屬性包含了服務(wù)器返回響應(yīng)文件的內(nèi)容。現(xiàn)在我們以XMLDocument對(duì)象方式返回響應(yīng),此時(shí)將不再需要reponseText屬性而使用responseXML屬性。
首先登陸金山通行證注冊(cè)頁面,我們發(fā)現(xiàn)金山通行證用戶名的檢測(cè)方式為:
pass.kingsoft.com/ksgweb/jsp/login/uid.jsp?uid=用戶名,并且返回XML數(shù)據(jù):
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <response> <method>isExistedUid</method> <result>-2</result> </response>
當(dāng)result值為-1時(shí)表示此用戶名已被注冊(cè),當(dāng)result值為-2時(shí)表示此用戶名尚未注冊(cè),因此通過對(duì)result值的判斷可以知道用戶名是否被注冊(cè)。
對(duì)上例代碼進(jìn)行修改:
首先找到
document.getElementById('message').innerHTML = xmlhttp_request.responseText;
改為:
var response = xmlhttp_request.responseXML.documentElement; var result = response.getElementsByTagName('result')[0].firstChild.data;//返回result節(jié)點(diǎn)數(shù)據(jù) if(result ==-2){ document.getElementById('message').innerHTML = "用戶名"+document.getElementById('163id').value+"尚未注冊(cè)"; } else if(result ==-1){ document.getElementById('message').innerHTML = "對(duì)不起,用戶名"+document.getElementById('163id').value+"已經(jīng)注冊(cè)"; }
通過以上兩個(gè)實(shí)例說明了AJAX的客戶端基礎(chǔ)應(yīng)用,采用的是網(wǎng)易和金山現(xiàn)成的服務(wù)器端程序,當(dāng)然為了開發(fā)合適自己頁面的程序,還需要對(duì)自己編寫服務(wù)器端程序,這設(shè)計(jì)到程序語言及數(shù)據(jù)庫的操作,對(duì)于有一定程序基礎(chǔ)的讀者一定不是很難的事情,本文著重討論了客戶端AJAX的應(yīng)用體驗(yàn),廣大讀者可以根據(jù)本文講的原理結(jié)合各種樣式表現(xiàn)手法作出絢麗多彩的應(yīng)用,希望本文能夠起到拋磚引玉的作用。
演示地址:
網(wǎng)易通行證查詢演示(AJAX): www.xiacong.com/test/163.htm
金山通行證查詢演示(AJAX): www.xiacong.com/test/j3.htm
附錄
(一) HTTP 1.1支持的狀態(tài)代碼
100 Continue 初始的請(qǐng)求已經(jīng)接受,客戶應(yīng)當(dāng)繼續(xù)發(fā)送請(qǐng)求的其余部分
101 Switching Protocols 服務(wù)器將遵從客戶的請(qǐng)求轉(zhuǎn)換到另外一種協(xié)議
200 OK 一切正常,對(duì)GET和POST請(qǐng)求的應(yīng)答文檔跟在后面。
201 Created 服務(wù)器已經(jīng)創(chuàng)建了文檔,Location頭給出了它的URL。
202 Accepted 已經(jīng)接受請(qǐng)求,但處理尚未完成。
203 Non-Authoritative Information 文檔已經(jīng)正常地返回,但一些應(yīng)答頭可能不正確,因?yàn)槭褂玫氖俏臋n的拷貝
204 No Content 沒有新文檔,瀏覽器應(yīng)該繼續(xù)顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個(gè)狀態(tài)代碼是很有用的
205 Reset Content 沒有新的內(nèi)容,但瀏覽器應(yīng)該重置它所顯示的內(nèi)容。用來強(qiáng)制瀏覽器清除表單輸入內(nèi)容
206 Partial Content 客戶發(fā)送了一個(gè)帶有Range頭的GET請(qǐng)求,服務(wù)器完成了它
300 Multiple Choices 客戶請(qǐng)求的文檔可以在多個(gè)位置找到,這些位置已經(jīng)在返回的文檔內(nèi)列出。如果服務(wù)器要提出優(yōu)先選擇,則應(yīng)該在Location應(yīng)答頭指明。
301 Moved Permanently 客戶請(qǐng)求的文檔在其他地方,新的URL在Location頭中給出,瀏覽器應(yīng)該自動(dòng)地訪問新的URL。
302 Found 類似于301,但新的URL應(yīng)該被視為臨時(shí)性的替代,而不是永久性的。
303 See Other 類似于301/302,不同之處在于,如果原來的請(qǐng)求是POST,Location頭指定的重定向目標(biāo)文檔應(yīng)該通過GET提取
304 Not Modified 客戶端有緩沖的文檔并發(fā)出了一個(gè)條件性的請(qǐng)求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務(wù)器告訴客戶,原來緩沖的文檔還可以繼續(xù)使用。
305 Use Proxy 客戶請(qǐng)求的文檔應(yīng)該通過Location頭所指明的代理服務(wù)器提取
307 Temporary Redirect 和302(Found)相同。許多瀏覽器會(huì)錯(cuò)誤地響應(yīng)302應(yīng)答進(jìn)行重定向,即使原來的請(qǐng)求是POST,即使它實(shí)際上只能在POST請(qǐng)求的應(yīng)答是303時(shí)才能重定向。由于這個(gè)原因,HTTP 1.1新增了307,以便更加清除地區(qū)分幾個(gè)狀態(tài)代碼:當(dāng)出現(xiàn)303應(yīng)答時(shí),瀏覽器可以跟隨重定向的GET和POST請(qǐng)求;如果是307應(yīng)答,則瀏覽器只能跟隨對(duì)GET請(qǐng)求的重定向。
400 Bad Request 請(qǐng)求出現(xiàn)語法錯(cuò)誤。
401 Unauthorized 客戶試圖未經(jīng)授權(quán)訪問受密碼保護(hù)的頁面。應(yīng)答中會(huì)包含一個(gè)WWW-Authenticate頭,瀏覽器據(jù)此顯示用戶名字/密碼對(duì)話框,然后在填寫合適的Authorization頭后再次發(fā)出請(qǐng)求。
403 Forbidden 資源不可用。
404 Not Found 無法找到指定位置的資源
405 Method Not Allowed 請(qǐng)求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)對(duì)指定的資源不適用。
406 Not Acceptable 指定的資源已經(jīng)找到,但它的MIME類型和客戶在Accpet頭中所指定的不兼容
407 Proxy Authentication Required 類似于401,表示客戶必須先經(jīng)過代理服務(wù)器的授權(quán)。
408 Request Timeout 在服務(wù)器許可的等待時(shí)間內(nèi),客戶一直沒有發(fā)出任何請(qǐng)求??蛻艨梢栽谝院笾貜?fù)同一請(qǐng)求。
409 Conflict 通常和PUT請(qǐng)求有關(guān)。由于請(qǐng)求和資源的當(dāng)前狀態(tài)相沖突,因此請(qǐng)求不能成功。
410 Gone 所請(qǐng)求的文檔已經(jīng)不再可用,而且服務(wù)器不知道應(yīng)該重定向到哪一個(gè)地址。它和404的不同在于,返回407表示文檔永久地離開了指定的位置,而404表示由于未知的原因文檔不可用。
411 Length Required 服務(wù)器不能處理請(qǐng)求,除非客戶發(fā)送一個(gè)Content-Length頭。
412 Precondition Failed 請(qǐng)求頭中指定的一些前提條件失敗
413 Request Entity Too Large 目標(biāo)文檔的大小超過服務(wù)器當(dāng)前愿意處理的大小。如果服務(wù)器認(rèn)為自己能夠稍后再處理該請(qǐng)求,則應(yīng)該提供一個(gè)Retry-After頭
414 Request URI Too Long URI太長(zhǎng)
416 Requested Range Not Satisfiable 服務(wù)器不能滿足客戶在請(qǐng)求中指定的Range頭
500 Internal Server Error 服務(wù)器遇到了意料不到的情況,不能完成客戶的請(qǐng)求
501 Not Implemented 服務(wù)器不支持實(shí)現(xiàn)請(qǐng)求所需要的功能。例如,客戶發(fā)出了一個(gè)服務(wù)器不支持的PUT請(qǐng)求
502 Bad Gateway 服務(wù)器作為網(wǎng)關(guān)或者代理時(shí),為了完成請(qǐng)求訪問下一個(gè)服務(wù)器,但該服務(wù)器返回了非法的應(yīng)答
503 Service Unavailable 服務(wù)器由于維護(hù)或者負(fù)載過重未能應(yīng)答。例如,Servlet可能在數(shù)據(jù)庫連接池已滿的情況下返回503。服務(wù)器返回503時(shí)可以提供一個(gè)Retry-After頭
504 Gateway Timeout 由作為代理或網(wǎng)關(guān)的服務(wù)器使用,表示不能及時(shí)地從遠(yuǎn)程服務(wù)器獲得應(yīng)答
505 HTTP Version Not Supported 服務(wù)器不支持請(qǐng)求中所指明的HTTP版本
(二) XMLHttpRequest 對(duì)象方法
abort() 停止當(dāng)前請(qǐng)求 getAllResponseHeaders() 作為字符串返問完整的headers getResponseHeader("headerLabel") 作為字符串返問單個(gè)的header標(biāo)簽 open("method","URL"[,asyncFlag[,"userName"[, "password"]]]) 設(shè)置未決的請(qǐng)求的目標(biāo) URL, 方法, 和其他參數(shù) send(content) 發(fā)送請(qǐng)求 setRequestHeader("label", "value") 設(shè)置header并和請(qǐng)求一起發(fā)送
(三) XMLHttpRequest 對(duì)象屬性
onreadystatechange 狀態(tài)改變的事件觸發(fā)器 readyState 對(duì)象狀態(tài)(integer):0 = 未初始化1 = 讀取中2 = 已讀取3 = 交互中4 = 完成 responseText 服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的文本版本 responseXML 服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的兼容DOM的XML文檔對(duì)象 status 服務(wù)器返回的狀態(tài)碼, 如:404 = "文件末找到" 、200 ="成功" statusText 服務(wù)器返回的狀態(tài)文本信息
使用XHTML和CSS標(biāo)準(zhǔn)化呈現(xiàn);
使用DOM實(shí)現(xiàn)動(dòng)態(tài)顯示和交互;
使用XML和XSLT進(jìn)行數(shù)據(jù)交換與處理;
使用XMLHttpRequest進(jìn)行異步數(shù)據(jù)讀取;
最后用JavaScript綁定和處理所有數(shù)據(jù);
Ajax的工作原理相當(dāng)于在用戶和服務(wù)器之間加了—個(gè)中間層,使用戶操作與服務(wù)器響應(yīng)異步化。這樣把以前的一些服務(wù)器負(fù)擔(dān)的工作轉(zhuǎn)嫁到客戶端,利于客戶端閑置的處理能力來處理,減輕服務(wù)器和帶寬的負(fù)擔(dān),從而達(dá)到節(jié)約ISP的空間及帶寬租用成本的目的。
我們以兩個(gè)驗(yàn)證通行證帳號(hào)是否存在的例子來講述AJAX在實(shí)際中的應(yīng)用:
(1)????用文本字符串的方式返回服務(wù)器的響應(yīng)來驗(yàn)證網(wǎng)易通行證帳號(hào)是否存在;
(2)????以XMLDocument對(duì)象方式返回響應(yīng)來驗(yàn)證金山通行證帳號(hào)是否存在;
首先,我們需要用JavaScript來創(chuàng)建XMLHttpRequest 類向服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求, XMLHttpRequest 類首先由Internet Explorer以ActiveX對(duì)象引入,被稱為XMLHTTP。 后來Mozilla﹑Netscape﹑Safari 和其他瀏覽器也提供了XMLHttpRequest類,不過它們創(chuàng)建XMLHttpRequest類的方法不同。
對(duì)于Internet Explorer瀏覽器,創(chuàng)建XMLHttpRequest 方法如下:
xmlhttp_request = new ActiveXObject("Msxml2.XMLHTTP.3.0"); //3.0或4.0, 5.0 xmlhttp_request = new ActiveXObject("Msxml2.XMLHTTP"); xmlhttp_request = new ActiveXObject("Microsoft.XMLHTTP");
由于在不同Internet Explorer瀏覽器中XMLHTTP版本可能不一致,為了更好的兼容不同版本的Internet Explorer瀏覽器,因此我們需要根據(jù)不同版本的Internet Explorer瀏覽器來創(chuàng)建XMLHttpRequest類,上面代碼就是根據(jù)不同的Internet Explorer瀏覽器創(chuàng)建XMLHttpRequest類的方法。
對(duì)于Mozilla﹑Netscape﹑Safari等瀏覽器,創(chuàng)建XMLHttpRequest 方法如下:
xmlhttp_request = new XMLHttpRequest();
如果服務(wù)器的響應(yīng)沒有XML mime-type header,某些Mozilla瀏覽器可能無法正常工作。 為了解決這個(gè)問題,如果服務(wù)器響應(yīng)的header不是text/xml,可以調(diào)用其它方法修改該header。
xmlhttp_request = new XMLHttpRequest(); xmlhttp_request.overrideMimeType('text/xml');
在實(shí)際應(yīng)用中,為了兼容多種不同版本的瀏覽器,一般將創(chuàng)建XMLHttpRequest類的方法寫成如下形式:
try{if( window.ActiveXObject ){for( var i = 5; i; i-- ){try{if( i == 2 ){ xmlhttp_request = new ActiveXObject( "Microsoft.XMLHTTP" ); }else{ xmlhttp_request = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" ); } xmlhttp_request.setRequestHeader("Content-Type","text/xml"); xmlhttp_request.setRequestHeader("Content-Type","gb2312"); break;}catch(e){ xmlhttp_request = false;}}}else if( window.XMLHttpRequest ){xmlhttp_request = new XMLHttpRequest();if (xmlhttp_request.overrideMimeType) {xmlhttp_request.overrideMimeType('text/xml');}}}catch(e){xmlhttp_request = false;}
在定義了如何處理響應(yīng)后,就要發(fā)送請(qǐng)求了??梢哉{(diào)用HTTP請(qǐng)求類的open()和send()方法,如下所示:
xmlhttp_request.open('GET', URL, true); xmlhttp_request.send(null);
open()的第一個(gè)參數(shù)是HTTP請(qǐng)求方式—GET,POST或任何服務(wù)器所支持的您想調(diào)用的方式。 按照HTTP規(guī)范,該參數(shù)要大寫;否則,某些瀏覽器(如Firefox)可能無法處理請(qǐng)求。
第二個(gè)參數(shù)是請(qǐng)求頁面的URL。
第三個(gè)參數(shù)設(shè)置請(qǐng)求是否為異步模式。如果是TRUE,JavaScript函數(shù)將繼續(xù)執(zhí)行,而不等待服務(wù)器響應(yīng)。這就是"AJAX"中的"A"。
用JavaScript來創(chuàng)建XMLHttpRequest 類向服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求后,接下來要決定當(dāng)收到服務(wù)器的響應(yīng)后,需要做什么。這需要告訴HTTP請(qǐng)求對(duì)象用哪一個(gè)JavaScript函數(shù)處理這個(gè)響應(yīng)??梢詫?duì)象的onreadystatechange屬性設(shè)置為要使用的JavaScript的函數(shù)名,如下所示:
xmlhttp_request.onreadystatechange =FunctionName;
FunctionName是用JavaScript創(chuàng)建的函數(shù)名,注意不要寫成FunctionName(),當(dāng)然我們也可以直接將JavaScript代碼創(chuàng)建在onreadystatechange之后,例如:
xmlhttp_request.onreadystatechange = function(){// JavaScript代碼段 };
在這個(gè)函數(shù)中。首先要檢查請(qǐng)求的狀態(tài)。只有當(dāng)一個(gè)完整的服務(wù)器響應(yīng)已經(jīng)收到了,函數(shù)才可以處理該響應(yīng)。XMLHttpRequest 提供了readyState屬性來對(duì)服務(wù)器響應(yīng)進(jìn)行判斷。
readyState的取值如下:
0 (未初始化)
1 (正在裝載)
2 (裝載完畢)
3 (交互中)
4 (完成)
所以只有當(dāng)readyState=4時(shí),一個(gè)完整的服務(wù)器響應(yīng)已經(jīng)收到了,函數(shù)才可以處理該響應(yīng)。具體代碼如下:
if (http_request.readyState == 4) {// 收到完整的服務(wù)器響應(yīng) } else {// 沒有收到完整的服務(wù)器響應(yīng) }
當(dāng)readyState=4時(shí),一個(gè)完整的服務(wù)器響應(yīng)已經(jīng)收到了,接著,函數(shù)會(huì)檢查HTTP服務(wù)器響應(yīng)的狀態(tài)值。完整的狀態(tài)取值可參見W3C文檔。當(dāng)HTTP服務(wù)器響應(yīng)的值為200時(shí),表示狀態(tài)正常。
在檢查完請(qǐng)求的狀態(tài)值和響應(yīng)的HTTP狀態(tài)值后,就可以處理從服務(wù)器得到的數(shù)據(jù)了。有兩種方式可以得到這些數(shù)據(jù):
(1)????以文本字符串的方式返回服務(wù)器的響應(yīng)
(2)????以XMLDocument對(duì)象方式返回響應(yīng)
實(shí)例一: 用文本字符串的方式返回服務(wù)器的響應(yīng)來驗(yàn)證網(wǎng)易通行證帳號(hào)是否存在
首先,我們登陸網(wǎng)易通行證注冊(cè)頁面,可以看到檢測(cè)用戶名是否存在是將用戶名提交給checkssn.jsp頁面進(jìn)行判斷,格式為:
reg.163.com/register/checkssn.jsp?username=用戶名
根據(jù)上面講到的方法,我們可以利用AJAX技術(shù)對(duì)網(wǎng)易通行證用戶名進(jìn)行檢測(cè):
第一步:新建一個(gè)基于Xhtml標(biāo)準(zhǔn)的網(wǎng)頁,在<head>區(qū)域插入Javascript函數(shù)如下:
<script type="text/javascript" language="javascript"> function getXMLRequester( ){var xmlhttp_request = false;try{if( window.ActiveXObject ){for( var i = 5; i; i-- ){try{if( i == 2 ){ xmlhttp_request = new ActiveXObject( "Microsoft.XMLHTTP" ); }else{ xmlhttp_request = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" ); xmlhttp_request.setRequestHeader("Content-Type","text/xml"); xmlhttp_request.setRequestHeader("Content-Type","gb2312");} break;}catch(e){ xmlhttp_request = false;}}}else if( window.XMLHttpRequest ){xmlhttp_request = new XMLHttpRequest();if (xmlhttp_request.overrideMimeType) {xmlhttp_request.overrideMimeType('text/xml');}}}catch(e){xmlhttp_request = false;}return xmlhttp_request ; }function IDRequest(n) {//定義收到服務(wù)器的響應(yīng)后需要執(zhí)行的JavaScript函數(shù) url=n+document.getElementById('163id').value;//定義網(wǎng)址參數(shù)xmlhttp_request=getXMLRequester();//調(diào)用創(chuàng)建XMLHttpRequest的函數(shù)xmlhttp_request.onreadystatechange = doContents;//調(diào)用doContents函數(shù)xmlhttp_request.open('GET', url, true);xmlhttp_request.send(null);}function doContents() {if (xmlhttp_request.readyState == 4) {// 收到完整的服務(wù)器響應(yīng)if (xmlhttp_request.status == 200) {//HTTP服務(wù)器響應(yīng)的值OK document.getElementById('message').innerHTML = xmlhttp_request.responseText; //將服務(wù)器返回的字符串寫到頁面中ID為message的區(qū)域} else {alert(http_request.status);}}} </script>
在<body>區(qū)域建立一個(gè)文本框,id為163id
<input type="text" id="163id" onpropertychange="IDRequest('http://reg.163.com/register/checkssn.jsp?username=')" />
再建一個(gè)id為messsge的空白區(qū)域用來顯示返回字符串(也可以通過Javascript函數(shù)截取一部分字符串顯示):
<div id="message"></div>
這樣,一個(gè)基于AJAX技術(shù)的用戶名檢測(cè)頁面就做好了,不過這個(gè)頁面將返回服務(wù)器響應(yīng)生成頁面的所有字符串,當(dāng)然還可以對(duì)返回的字符串進(jìn)行一些操作,便于應(yīng)用到不同的需要當(dāng)中。
實(shí)例二: 以XMLDocument對(duì)象方式返回響應(yīng)來驗(yàn)證金山通行證帳號(hào)是否存在
在上面的例子中,當(dāng)服務(wù)器對(duì)HTTP請(qǐng)求的響應(yīng)被收到后,我們會(huì)調(diào)用請(qǐng)求對(duì)象的reponseText屬性。該屬性包含了服務(wù)器返回響應(yīng)文件的內(nèi)容。現(xiàn)在我們以XMLDocument對(duì)象方式返回響應(yīng),此時(shí)將不再需要reponseText屬性而使用responseXML屬性。
首先登陸金山通行證注冊(cè)頁面,我們發(fā)現(xiàn)金山通行證用戶名的檢測(cè)方式為:
pass.kingsoft.com/ksgweb/jsp/login/uid.jsp?uid=用戶名,并且返回XML數(shù)據(jù):
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <response> <method>isExistedUid</method> <result>-2</result> </response>
當(dāng)result值為-1時(shí)表示此用戶名已被注冊(cè),當(dāng)result值為-2時(shí)表示此用戶名尚未注冊(cè),因此通過對(duì)result值的判斷可以知道用戶名是否被注冊(cè)。
對(duì)上例代碼進(jìn)行修改:
首先找到
document.getElementById('message').innerHTML = xmlhttp_request.responseText;
改為:
var response = xmlhttp_request.responseXML.documentElement; var result = response.getElementsByTagName('result')[0].firstChild.data;//返回result節(jié)點(diǎn)數(shù)據(jù) if(result ==-2){ document.getElementById('message').innerHTML = "用戶名"+document.getElementById('163id').value+"尚未注冊(cè)"; } else if(result ==-1){ document.getElementById('message').innerHTML = "對(duì)不起,用戶名"+document.getElementById('163id').value+"已經(jīng)注冊(cè)"; }
通過以上兩個(gè)實(shí)例說明了AJAX的客戶端基礎(chǔ)應(yīng)用,采用的是網(wǎng)易和金山現(xiàn)成的服務(wù)器端程序,當(dāng)然為了開發(fā)合適自己頁面的程序,還需要對(duì)自己編寫服務(wù)器端程序,這設(shè)計(jì)到程序語言及數(shù)據(jù)庫的操作,對(duì)于有一定程序基礎(chǔ)的讀者一定不是很難的事情,本文著重討論了客戶端AJAX的應(yīng)用體驗(yàn),廣大讀者可以根據(jù)本文講的原理結(jié)合各種樣式表現(xiàn)手法作出絢麗多彩的應(yīng)用,希望本文能夠起到拋磚引玉的作用。
演示地址:
網(wǎng)易通行證查詢演示(AJAX): www.xiacong.com/test/163.htm
金山通行證查詢演示(AJAX): www.xiacong.com/test/j3.htm
附錄
(一) HTTP 1.1支持的狀態(tài)代碼
100 Continue 初始的請(qǐng)求已經(jīng)接受,客戶應(yīng)當(dāng)繼續(xù)發(fā)送請(qǐng)求的其余部分
101 Switching Protocols 服務(wù)器將遵從客戶的請(qǐng)求轉(zhuǎn)換到另外一種協(xié)議
200 OK 一切正常,對(duì)GET和POST請(qǐng)求的應(yīng)答文檔跟在后面。
201 Created 服務(wù)器已經(jīng)創(chuàng)建了文檔,Location頭給出了它的URL。
202 Accepted 已經(jīng)接受請(qǐng)求,但處理尚未完成。
203 Non-Authoritative Information 文檔已經(jīng)正常地返回,但一些應(yīng)答頭可能不正確,因?yàn)槭褂玫氖俏臋n的拷貝
204 No Content 沒有新文檔,瀏覽器應(yīng)該繼續(xù)顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個(gè)狀態(tài)代碼是很有用的
205 Reset Content 沒有新的內(nèi)容,但瀏覽器應(yīng)該重置它所顯示的內(nèi)容。用來強(qiáng)制瀏覽器清除表單輸入內(nèi)容
206 Partial Content 客戶發(fā)送了一個(gè)帶有Range頭的GET請(qǐng)求,服務(wù)器完成了它
300 Multiple Choices 客戶請(qǐng)求的文檔可以在多個(gè)位置找到,這些位置已經(jīng)在返回的文檔內(nèi)列出。如果服務(wù)器要提出優(yōu)先選擇,則應(yīng)該在Location應(yīng)答頭指明。
301 Moved Permanently 客戶請(qǐng)求的文檔在其他地方,新的URL在Location頭中給出,瀏覽器應(yīng)該自動(dòng)地訪問新的URL。
302 Found 類似于301,但新的URL應(yīng)該被視為臨時(shí)性的替代,而不是永久性的。
303 See Other 類似于301/302,不同之處在于,如果原來的請(qǐng)求是POST,Location頭指定的重定向目標(biāo)文檔應(yīng)該通過GET提取
304 Not Modified 客戶端有緩沖的文檔并發(fā)出了一個(gè)條件性的請(qǐng)求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務(wù)器告訴客戶,原來緩沖的文檔還可以繼續(xù)使用。
305 Use Proxy 客戶請(qǐng)求的文檔應(yīng)該通過Location頭所指明的代理服務(wù)器提取
307 Temporary Redirect 和302(Found)相同。許多瀏覽器會(huì)錯(cuò)誤地響應(yīng)302應(yīng)答進(jìn)行重定向,即使原來的請(qǐng)求是POST,即使它實(shí)際上只能在POST請(qǐng)求的應(yīng)答是303時(shí)才能重定向。由于這個(gè)原因,HTTP 1.1新增了307,以便更加清除地區(qū)分幾個(gè)狀態(tài)代碼:當(dāng)出現(xiàn)303應(yīng)答時(shí),瀏覽器可以跟隨重定向的GET和POST請(qǐng)求;如果是307應(yīng)答,則瀏覽器只能跟隨對(duì)GET請(qǐng)求的重定向。
400 Bad Request 請(qǐng)求出現(xiàn)語法錯(cuò)誤。
401 Unauthorized 客戶試圖未經(jīng)授權(quán)訪問受密碼保護(hù)的頁面。應(yīng)答中會(huì)包含一個(gè)WWW-Authenticate頭,瀏覽器據(jù)此顯示用戶名字/密碼對(duì)話框,然后在填寫合適的Authorization頭后再次發(fā)出請(qǐng)求。
403 Forbidden 資源不可用。
404 Not Found 無法找到指定位置的資源
405 Method Not Allowed 請(qǐng)求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)對(duì)指定的資源不適用。
406 Not Acceptable 指定的資源已經(jīng)找到,但它的MIME類型和客戶在Accpet頭中所指定的不兼容
407 Proxy Authentication Required 類似于401,表示客戶必須先經(jīng)過代理服務(wù)器的授權(quán)。
408 Request Timeout 在服務(wù)器許可的等待時(shí)間內(nèi),客戶一直沒有發(fā)出任何請(qǐng)求??蛻艨梢栽谝院笾貜?fù)同一請(qǐng)求。
409 Conflict 通常和PUT請(qǐng)求有關(guān)。由于請(qǐng)求和資源的當(dāng)前狀態(tài)相沖突,因此請(qǐng)求不能成功。
410 Gone 所請(qǐng)求的文檔已經(jīng)不再可用,而且服務(wù)器不知道應(yīng)該重定向到哪一個(gè)地址。它和404的不同在于,返回407表示文檔永久地離開了指定的位置,而404表示由于未知的原因文檔不可用。
411 Length Required 服務(wù)器不能處理請(qǐng)求,除非客戶發(fā)送一個(gè)Content-Length頭。
412 Precondition Failed 請(qǐng)求頭中指定的一些前提條件失敗
413 Request Entity Too Large 目標(biāo)文檔的大小超過服務(wù)器當(dāng)前愿意處理的大小。如果服務(wù)器認(rèn)為自己能夠稍后再處理該請(qǐng)求,則應(yīng)該提供一個(gè)Retry-After頭
414 Request URI Too Long URI太長(zhǎng)
416 Requested Range Not Satisfiable 服務(wù)器不能滿足客戶在請(qǐng)求中指定的Range頭
500 Internal Server Error 服務(wù)器遇到了意料不到的情況,不能完成客戶的請(qǐng)求
501 Not Implemented 服務(wù)器不支持實(shí)現(xiàn)請(qǐng)求所需要的功能。例如,客戶發(fā)出了一個(gè)服務(wù)器不支持的PUT請(qǐng)求
502 Bad Gateway 服務(wù)器作為網(wǎng)關(guān)或者代理時(shí),為了完成請(qǐng)求訪問下一個(gè)服務(wù)器,但該服務(wù)器返回了非法的應(yīng)答
503 Service Unavailable 服務(wù)器由于維護(hù)或者負(fù)載過重未能應(yīng)答。例如,Servlet可能在數(shù)據(jù)庫連接池已滿的情況下返回503。服務(wù)器返回503時(shí)可以提供一個(gè)Retry-After頭
504 Gateway Timeout 由作為代理或網(wǎng)關(guān)的服務(wù)器使用,表示不能及時(shí)地從遠(yuǎn)程服務(wù)器獲得應(yīng)答
505 HTTP Version Not Supported 服務(wù)器不支持請(qǐng)求中所指明的HTTP版本
(二) XMLHttpRequest 對(duì)象方法
abort() 停止當(dāng)前請(qǐng)求 getAllResponseHeaders() 作為字符串返問完整的headers getResponseHeader("headerLabel") 作為字符串返問單個(gè)的header標(biāo)簽 open("method","URL"[,asyncFlag[,"userName"[, "password"]]]) 設(shè)置未決的請(qǐng)求的目標(biāo) URL, 方法, 和其他參數(shù) send(content) 發(fā)送請(qǐng)求 setRequestHeader("label", "value") 設(shè)置header并和請(qǐng)求一起發(fā)送
(三) XMLHttpRequest 對(duì)象屬性
onreadystatechange 狀態(tài)改變的事件觸發(fā)器 readyState 對(duì)象狀態(tài)(integer):0 = 未初始化1 = 讀取中2 = 已讀取3 = 交互中4 = 完成 responseText 服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的文本版本 responseXML 服務(wù)器進(jìn)程返回?cái)?shù)據(jù)的兼容DOM的XML文檔對(duì)象 status 服務(wù)器返回的狀態(tài)碼, 如:404 = "文件末找到" 、200 ="成功" statusText 服務(wù)器返回的狀態(tài)文本信息
轉(zhuǎn)載于:https://www.cnblogs.com/kangtr/archive/2005/12/11/295134.html
總結(jié)
以上是生活随笔為你收集整理的[转]WEB2.0中AJAX应用的详细探讨的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无法启动计算机丢失rtutils,丢失d
- 下一篇: 永磁同步电机(PMSM)的FOC闭环控制