AJAX非同步的 JavaScript
什麼是AJAX:
AJAX = Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML)。
AJAX 不是新的程式語言,而是一種使用現有標準的新方法。
AJAX 是與伺服器交換資料並更新部分網頁的藝術,在不重新載入整個頁面的情況下。
AJAX 是一種在無需重新載入整個網頁的情況下,能夠更新部分網頁的技術。
AJAX 是一種用於建立快速動態網頁的技術。
通過在後臺與伺服器進行少量資料交換,AJAX 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。
傳統的網頁(不使用 AJAX)如果需要更新內容,必需過載整個網頁面。
有很多使用 AJAX 的應用程式案例:新浪微博、Google 地圖、開心網等等。
Google Suggest
在 2005 年,Google 通過其 Google Suggest 使 AJAX 變得流行起來。
Google Suggest 使用 AJAX 創造出動態性極強的 web 介面:當您在谷歌的搜尋框輸入關鍵字時,JavaScript 會把這些字元傳送到伺服器,然後伺服器會返回一個搜尋建議的列表。
建立 XMLHttpRequest 物件
所有現代瀏覽器(IE7+、Firefox、Chrome、Safari 以及 Opera)均內建 XMLHttpRequest 物件。
建立 XMLHttpRequest 物件的語法:
variable=new XMLHttpRequest();
老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 物件:
variable=new ActiveXObject("Microsoft.XMLHTTP");
為了應對所有的現代瀏覽器,包括 IE5 和 IE6,請檢查瀏覽器是否支援 XMLHttpRequest 物件。如果支援,則建立 XMLHttpRequest 物件。如果不支援,則建立 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"); }
AJAX - 向伺服器傳送請求
XMLHttpRequest 物件用於和伺服器交換資料。
向伺服器傳送請求
如需將請求傳送到伺服器,我們使用 XMLHttpRequest 物件的 open() 和 send() 方法:
xmlhttp.open("GET","test1.txt",true); xmlhttp.send();
方法 | 描述 |
---|---|
open(method,url,async) | 規定請求的型別、URL 以及是否非同步處理請求。
|
send(string) | 將請求傳送到伺服器。
|
GET 還是 POST?
與 POST 相比,GET 更簡單也更快,並且在大部分情況下都能用。
然而,在以下情況中,請使用 POST 請求:
- 無法使用快取檔案(更新伺服器上的檔案或資料庫)
- 向伺服器傳送大量資料(POST 沒有資料量限制)
- 傳送包含未知字元的使用者輸入時,POST 比 GET 更穩定也更可靠
GET 請求
一個簡單的 GET 請求:
為了避免這種情況,請向 URL 新增一個唯一的 ID:
xmlhttp.open("GET","demo_get.asp?t=" + Math.random()
,true);
xmlhttp.send();
如果您希望通過 GET 方法傳送資訊,請向 URL 新增資訊:
xmlhttp.open("GET","demo_get2.asp?fname=Bill&lname=Gates",true); xmlhttp.send();
POST 請求
一個簡單 POST 請求:
xmlhttp.open("POST","demo_post.asp",true); xmlhttp.send();
如果需要像 HTML 表單那樣 POST 資料,請使用 setRequestHeader() 來新增 HTTP 頭。然後在 send() 方法中規定您希望傳送的資料:
xmlhttp.open("POST","ajax_test.asp",true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("fname=Bill&lname=Gates");
方法 | 描述 |
---|---|
setRequestHeader(header,value) | 向請求新增 HTTP 頭。
|
非同步 - True 或 False?
AJAX 指的是非同步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
XMLHttpRequest 物件如果要用於 AJAX 的話,其 open() 方法的 async 引數必須設定為 true:
xmlhttp.open("GET","ajax_test.asp",true
);
對於 web 開發人員來說,傳送非同步請求是一個巨大的進步。很多在伺服器執行的任務都相當費時。AJAX 出現之前,這可能會引起應用程式掛起或停止。
通過 AJAX,JavaScript 無需等待伺服器的響應,而是:
- 在等待伺服器響應時執行其他指令碼
- 當響應就緒後對響應進行處理
Async = true
當使用 async=true 時,請規定在響應處於 onreadystatechange 事件中的就緒狀態時執行的函式: xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } } xmlhttp.open("GET","test1.txt",true); xmlhttp.send();
伺服器響應
如需獲得來自伺服器的響應,請使用 XMLHttpRequest 物件的 responseText 或 responseXML 屬性。
屬性 | 描述 |
---|---|
responseText | 獲得字串形式的響應資料。 |
responseXML | 獲得 XML 形式的響應資料。 |
responseText 屬性
如果來自伺服器的響應並非 XML,請使用 responseText 屬性。
responseText 屬性返回字串形式的響應,因此您可以這樣使用:
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
responseXML 屬性
如果來自伺服器的響應是 XML,而且需要作為 XML 物件進行解析,請使用 responseXML 屬性:
請求 books.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;
AJAX - onreadystatechange 事件
onreadystatechange 事件
當請求被髮送到伺服器時,我們需要執行一些基於響應的任務。
每當 readyState 改變時,就會觸發 onreadystatechange 事件。
readyState 屬性存有 XMLHttpRequest 的狀態資訊。
下面是 XMLHttpRequest 物件的三個重要的屬性:
屬性 | 描述 |
---|---|
onreadystatechange | 儲存函式(或函式名),每當 readyState 屬性改變時,就會呼叫該函式。 |
readyState | 存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。
|
status | 200: "OK" 404: 未找到頁面 |
在 onreadystatechange 事件中,我們規定當伺服器響應已做好被處理的準備時所執行的任務。
當 readyState 等於 4 且狀態為 200 時,表示響應已就緒:
xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } }
註釋:onreadystatechange 事件被觸發 5 次(0 - 4),對應著 readyState 的每個變化。
使用 Callback 函式
callback 函式是一種以引數形式傳遞給另一個函式的函式。
如果您的網站上存在多個 AJAX 任務,那麼您應該為建立 XMLHttpRequest 物件編寫一個標準的函式,併為每個 AJAX 任務呼叫該函式。
該函式呼叫應該包含 URL 以及發生 onreadystatechange 事件時執行的任務(每次呼叫可能不盡相同):
function myFunction() { loadXMLDoc("ajax_info.txt",function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } }); }
AJAX ASP/PHP 例項
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> function showHint(str) { var xmlhttp; if (str.length==0) { document.getElementById("txtHint").innerHTML=""; return; } if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行程式碼 xmlhttp=new XMLHttpRequest(); } else { // IE6, IE5 瀏覽器執行程式碼 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("txtHint").innerHTML=xmlhttp.responseText; } } xmlhttp.open("GET","/try/ajax/gethint.php?q="+str,true); xmlhttp.send(); } </script> </head> <body> <h3>在輸入框中嘗試輸入字母 a:</h3> <form action=""> 輸入姓名: <input type="text" id="txt1" onkeyup="showHint(this.value)" /> </form> <p>提示資訊: <span id="txtHint"></span></p> </body> </html>
在輸入框中嘗試輸入字母 a:
提示資訊:
AJAX 伺服器頁面 - ASP 和 PHP
由上面的 JavaScript 呼叫的伺服器頁面是 ASP 檔案,名為 "gethint.asp"。
下面,我們建立了兩個版本的伺服器檔案,一個用 ASP 編寫,另一個用 PHP 編寫。
ASP 檔案
"gethint.asp" 中的原始碼會檢查一個名字陣列,然後向瀏覽器返回相應的名字:
<% response.expires=-1 dim a(30) 'Fill up array with names a(1)="Anna" a(2)="Brittany" a(3)="Cinderella" a(4)="Diana" a(5)="Eva" a(6)="Fiona" a(7)="Gunda" a(8)="Hege" a(9)="Inga" a(10)="Johanna" a(11)="Kitty" a(12)="Linda" a(13)="Nina" a(14)="Ophelia" a(15)="Petunia" a(16)="Amanda" a(17)="Raquel" a(18)="Cindy" a(19)="Doris" a(20)="Eve" a(21)="Evita" a(22)="Sunniva" a(23)="Tove" a(24)="Unni" a(25)="Violet" a(26)="Liza" a(27)="Elizabeth" a(28)="Ellen" a(29)="Wenche" a(30)="Vicky" 'get the q parameter from URL q=ucase(request.querystring("q")) 'lookup all hints from array if length of q>0 if len(q)>0 then hint="" for i=1 to 30 if q=ucase(mid(a(i),1,len(q))) then if hint="" then hint=a(i) else hint=hint & " , " & a(i) end if end if next end if 'Output "no suggestion" if no hint were found 'or output the correct values if hint="" then response.write("no suggestion") else response.write(hint) end if %>
PHP 檔案
下面的程式碼用 PHP 編寫,與上面的 ASP 程式碼作用是一樣的。
<?php // Fill up array with names $a[]="Anna"; $a[]="Brittany"; $a[]="Cinderella"; $a[]="Diana"; $a[]="Eva"; $a[]="Fiona"; $a[]="Gunda"; $a[]="Hege"; $a[]="Inga"; $a[]="Johanna"; $a[]="Kitty"; $a[]="Linda"; $a[]="Nina"; $a[]="Ophelia"; $a[]="Petunia"; $a[]="Amanda"; $a[]="Raquel"; $a[]="Cindy"; $a[]="Doris"; $a[]="Eve"; $a[]="Evita"; $a[]="Sunniva"; $a[]="Tove"; $a[]="Unni"; $a[]="Violet"; $a[]="Liza"; $a[]="Elizabeth"; $a[]="Ellen"; $a[]="Wenche"; $a[]="Vicky"; //get the q parameter from URL $q=$_GET["q"]; //lookup all hints from array if length of q>0 if (strlen($q) > 0) { $hint=""; for($i=0; $i<count($a); $i++) { if (strtolower($q)==strtolower(substr($a[$i],0,strlen($q)))) { if ($hint=="") { $hint=$a[$i]; } else { $hint=$hint." , ".$a[$i]; } } } } // Set output to "no suggestion" if no hint were found // or to the correct values if ($hint == "") { $response="no suggestion"; } else { $response=$hint; } //output the response echo $response; ?>