所有現(xiàn)代瀏覽器(IE7+、Firefox、Chrome、Safari 以及 Opera)均內建 XMLHttpRequest 對象。
創(chuàng)建XMLHttpRequest 對象的語法:
variable=new?XMLHttpRequest();
老版本的Internet Explorer (IE5 和 IE6)使用 ActiveX 對象:?
variable=new?ActiveXObject("Microsoft.XMLHTTP");
為了應對所有的現(xiàn)代瀏覽器,包括IE5 和 IE6,請檢查瀏覽器是否支持 XMLHttpRequest 對象。如果支持,則創(chuàng)建 XMLHttpRequest 對象。如果不支持,則創(chuàng)建 ActiveXObject ::
實例
var xmlhttp;if (window.XMLHttpRequest)? {// code for IE7+, Firefox, Chrome, Opera, Safari? xmlhttp=new XMLHttpRequest();? }else? {// code for IE6, IE5? xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");? }
XMLHttpRequest對象的屬性
XMLHttpRequest對象的常見屬性如下:
屬性描述
onreadystatechange存儲函數(shù)(或函數(shù)名),每當readyState的屬性改變時,就會調用該函數(shù)。
readyState存有的XMLHttpRequest的狀態(tài)從0到4發(fā)生變化。0:請求未初始化1:服務器連接已建立2:請求已接收3:請求處理中4:請求已完成,且響應已就緒
reponseText以文本形式返回響應。
responseXML以XML格式返回響應
status將狀態(tài)返回為數(shù)字(例如,“Not Found”為404,“OK”為200)
statusText以字符串形式返回狀態(tài)(例如,“Not Found”或“OK”)
XMLHttpRequest對象的方法
XMLHttpRequest對象的重要方法如下:
方法描述
abort()取消當前請求。
getAllResponseHeaders()以字符串形式返回完整的HTTP標頭集。
getResponseHeader( headerName )返回指定HTTP標頭的值。
void open(method,URL)打開指定獲取或交的方法和URL的請求。
void open(method,URL,async)與上面相同,但指定異步或不。
void open(method,URL,async,userName,password)與上面相同,但指定用戶名和密碼。
void send(content)發(fā)送獲取請求。
setRequestHeader(?label,value)將標簽/值對添加到要發(fā)送的HTTP標頭。
向服務器發(fā)送請求
如需將請求發(fā)送到服務器,我們使用XMLHttpRequest 對象的open()和send()方法:
xmlhttp.open("GET","ajax_info.txt",true); ???????
xmlhttp.send();
方法描述
open(method,url,async)規(guī)定請求的類型、URL 以及是否異步處理請求。
[if !supportLists]·?[endif]
method:請求的類型;GET 或 POST
[if !supportLists]·?[endif]
[if !supportLists]·?[endif]
url:文件在服務器上的位置
[if !supportLists]·?[endif]
[if !supportLists]·?[endif]
async:true(異步)或 false(同步)
[if !supportLists]·?[endif]
send(string)將請求發(fā)送到服務器。
[if !supportLists]·?[endif]
string:僅用于 POST 請求
[if !supportLists]·?[endif]
GET 還是 POST?
與POST相比,GET 更簡單也更快,并且在大部分情況下都能用。
然而,在以下情況中,請使用POST請求:
無法使用緩存文件(更新服務器上的文件或數(shù)據(jù)庫)
向服務器發(fā)送大量數(shù)據(jù)(POST沒有數(shù)據(jù)量限制)
發(fā)送包含未知字符的用戶輸入時,POST比GET更穩(wěn)定也更可靠
GET 請求
一個簡單的GET請求:
實例
xmlhttp.open("GET","demo_get.html",true);xmlhttp.send();
在上面的例子中,您可能得到的是緩存的結果。
為了避免這種情況,請向URL 添加一個唯一的 ID:
實例
xmlhttp.open("GET","demo_get.html?t=" + Math.random(),true);xmlhttp.send();
如果您希望通過GET方法發(fā)送信息,請向URL 添加信息:
實例
xmlhttp.open("GET","demo_get2.html?fname=Henry&lname=Ford",true);xmlhttp.send();
提示:GET請求具有以下的幾個特點:
GET請求可被緩存
GET請求保留在瀏覽器歷史記錄中
GET請求可被收藏為書簽
GET請求不應在處理敏感數(shù)據(jù)時使用
GET請求有長度限制
GET請求只應當用于取回數(shù)據(jù)
POST 請求
一個簡單POST請求:
實例
xmlhttp.open("POST","demo_post.html",true);xmlhttp.send();
如果需要像HTML 表單那樣 POST 數(shù)據(jù),請使用setRequestHeader()來添加HTTP 頭。然后在send()方法中規(guī)定您希望發(fā)送的數(shù)據(jù):
實例
xmlhttp.open("POST","ajax_test.html",true);xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");xmlhttp.send("fname=Henry&lname=Ford");
方法描述
setRequestHeader(header,value)向請求添加 HTTP 頭。
header: 規(guī)定頭的名稱
value: 規(guī)定頭的值
提示:POST請求的特點如下:
POST請求不會被緩存
POST請求不會保留在瀏覽器歷史記錄中
POST請求不能被收藏為書簽
POST請求對數(shù)據(jù)長度沒有要求
url - 服務器上的文件
open()方法的url參數(shù)是服務器上文件的地址:
xmlhttp.open("GET","ajax_test.html",true);
該文件可以是任何類型的文件,比如.txt和.xml,或者服務器腳本文件,比如.asp和.php(在傳回響應之前,能夠在服務器上執(zhí)行任務)。
異步- True 或 False?
AJAX 指的是異步JavaScript?和 XML(Asynchronous JavaScript and XML)。
XMLHttpRequest 對象如果要用于 AJAX 的話,其open()方法的sync參數(shù)必須設置為true:
xmlhttp.open("GET","ajax_test.html",true);
對于web 開發(fā)人員來說,發(fā)送異步請求是一個巨大的進步。很多在服務器執(zhí)行的任務都相當費時。AJAX 出現(xiàn)之前,這可能會引起應用程序掛起或停止。
通過AJAX,JavaScript 無需等待服務器的響應,而是:
在等待服務器響應時執(zhí)行其他腳本
當響應就緒后對響應進行處理
Async=true
當使用async=true 時,請規(guī)定在響應處于 onreadystatechange 事件中的就緒狀態(tài)時執(zhí)行的函數(shù):
實例
xmlhttp.onreadystatechange=function()? {? if (xmlhttp.readyState==4 && xmlhttp.status==200)??? {??? document.getElementById("myDiv").innerHTML=xmlhttp.responseText;??? }? }xmlhttp.open("GET","ajax_info.txt",true);xmlhttp.send();
Async = false
如需使用async=false,請將open()方法中的第三個參數(shù)改為false:
xmlhttp.open("GET","test1.txt",false);
我們不推薦使用async=false,但是對于一些小型的請求,也是可以的。
請記住,JavaScript 會等到服務器響應就緒才繼續(xù)執(zhí)行。如果服務器繁忙或緩慢,應用程序會掛起或停止。
注意:當您使用async=false 時,請不要編寫 onreadystatechange 函數(shù) - 把代碼放到send()語句后面即可:
實例
xmlhttp.open("GET","ajax_info.txt",false);xmlhttp.send();document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
XHR 響應
AJAX - 服務器響應
由于HTTP 響應是由服務端發(fā)出的,并且服務器做出響應需要時間(比如網(wǎng)速慢等原因),所以我們需要監(jiān)聽服務器響應的狀態(tài),然后才能進行處理。
狀態(tài)行xhr.status狀態(tài)碼,如200,304,404等;
響應主體xhr.responseText與xhr.responseXML都表示響應主體。
如需獲得來自服務器的響應,請使用XMLHttpRequest 對象的responseText或responseXML屬性。
屬性描述
responseText獲得字符串形式的響應數(shù)據(jù)。
responseXML獲得 XML 形式的響應數(shù)據(jù)。
responseText 屬性
如果來自服務器的響應并非XML,請使用responseText屬性。
responseText屬性返回字符串形式的響應,因此您可以這樣使用:
實例
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
responseXML 屬性
如果來自服務器的響應是XML,而且需要作為 XML 對象進行解析,請使用responseXML屬性:
實例
請求cd_catalog.xml?文件,并解析響應:
xmlDoc=xmlhttp.responseXML;txt="";x=xmlDoc.getElementsByTagName("ARTIST");for (i=0;i<x.length;i++)? {? txt=txt + x[i].childNodes[0].nodeValue + "<br>";? }document.getElementById("myDiv").innerHTML=txt;
XHR readyState
AJAX -?onreadystatechange?事件
當發(fā)送一個請求后,客戶端需要確定這個請求什么時候會完成,因此,XMLHttpRequest對象提供了onreadystatechange事件機制來捕獲請求的狀態(tài),繼而實現(xiàn)響應。
當請求被發(fā)送到服務器時,我們需要執(zhí)行一些基于響應的任務。
每當readyState改變時,就會觸發(fā)onreadystatechange事件。
readyState屬性存有XMLHttpRequest 的狀態(tài)信息。
下面是XMLHttpRequest 對象的三個重要的屬性:
屬性描述
onreadystatechange存儲函數(shù)(或函數(shù)名),每當readyState屬性改變時,就會調用該函數(shù)。
readyState存有 XMLHttpRequest 的狀態(tài)。從 0 到 4 發(fā)生變化。
0: 請求未初始化
1: 服務器連接已建立
2: 請求已接收
3: 請求處理中
4: 請求已完成,且響應已就緒
status200: "OK"404: 未找到頁面
readyState狀態(tài)說明
0:請求未初始化
此階段確認XMLHttpRequest對象是否創(chuàng)建,并為調用open()方法進行未初始化作好準備,值為0表示對象已經(jīng)存在,否則瀏覽器會報錯:對象不存在。
1:服務器連接已建立
此階段對XMLHttpRequest對象進行初始化,即調用open()方法,根據(jù)參數(shù)(method,url,true)完成對象狀態(tài)的設置。并調用send()方法開始向服務端發(fā)送請求。
值為1表示正在向服務端發(fā)送請求。
2:請求已接收
此階段接收服務器端的響應數(shù)據(jù)。但獲得的還只是服務端響應的原始數(shù)據(jù),并不能直接在客戶端使用。
值為2表示已經(jīng)接收完全部響應數(shù)據(jù),并為下一階段對數(shù)據(jù)解析作好準備。
3:請求處理中
此階段解析接收到的服務器端響應數(shù)據(jù)即根據(jù)服務器端響應頭部返回的MIME類型把數(shù)據(jù)轉換成能通過responseBody,responseText或responseXML的屬性存取的格式,為在客戶端調用作好準備。
狀態(tài)3表示正在解析數(shù)據(jù)。
4:請求已完成,且響應已就緒
此階段確認全部數(shù)據(jù)都已經(jīng)解析為客戶端可用的格式,解析已經(jīng)完成。值為4表示數(shù)據(jù)解析完畢,可以通過的XMLHttpRequest對象的屬性取得數(shù)據(jù)。
概而括之,整個XMLHttpRequest對象的生命周期應該包含如下階段:
1.創(chuàng)建2.初始化請求3.發(fā)送請求4.接收數(shù)據(jù)5.解析數(shù)據(jù)6.完成
在onreadystatechange事件中,我們規(guī)定當服務器響應已做好被處理的準備時所執(zhí)行的任務。
當readyState等于4 且狀態(tài)為 200 時,表示響應已就緒:
實例
xmlhttp.onreadystatechange=function()? {? if (xmlhttp.readyState==4 && xmlhttp.status==200)??? {??? document.getElementById("myDiv").innerHTML=xmlhttp.responseText;??? }? }
在onreadystatechange事件中,我們規(guī)定當服務器響應已做好被處理的準備時所執(zhí)行的任務。
當readyState等于4 且狀態(tài)為 200 時,表示響應已就緒:
實例
xmlhttp.onreadystatechange=function()? {? if (xmlhttp.readyState==4 && xmlhttp.status==200)??? {??? document.getElementById("myDiv").innerHTML=xmlhttp.responseText;??? }? }
使用回調函數(shù)
回調函數(shù)是一種以參數(shù)形式傳遞給另一個函數(shù)的函數(shù)。
如果您的網(wǎng)站上存在多個AJAX 任務,那么您應該為創(chuàng)建 XMLHttpRequest 對象編寫一個標準的函數(shù),并為每個AJAX 任務調用該函數(shù)。
該函數(shù)調用應該包含URL 以及發(fā)生onreadystatechange事件時執(zhí)行的任務(每次調用可能不盡相同):
實例
function myFunction(){loadXMLDoc("ajax_info.txt",function()? {? if (xmlhttp.readyState==4 && xmlhttp.status==200)??? {??? document.getElementById("myDiv").innerHTML=xmlhttp.responseText;??? }? });}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
var xmlhttp;
function loadXMLDoc(url,cfunc)
{
if (window.XMLHttpRequest)
??{// IE7+, Firefox, Chrome, Opera, Safari 代碼
??xmlhttp=new XMLHttpRequest();
??}
else
??{// IE6, IE5 代碼
??xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
??}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function myFunction()
{
loadXMLDoc("/statics/demosource/ajax_info.txt",function()
??{
??if (xmlhttp.readyState==4 && xmlhttp.status==200)
????{
????document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
????}
??});
}
</script>
</head>
<body>
<div id="myDiv"><h2>使用 AJAX 修改文本內容</h2></div>
<button type="button" onclick="myFunction()">修改內容</button>
</body>
</html>