AJAX 上手篇
出自 MozTW Wiki
編譯中: --BobChao 19:48 2005年九月21日 (CST)
這篇文章說明 AJAX 相關技術的基礎,並提供實例供您上手。本文編譯自 AJAX:Getting Started,在 devmo 有中文版之後可能會移過去。
內容大綱
AJAX 是啥?
AJAX (Asynchronous JavaScript and XML) 是個新詞,但內涵是兩個存在已有一段時間的 JavaScript 功能。這兩種功能以往一直被忽略,在 Gmail、Google suggest 及 Google Maps 出現後才一舉成名天下知。
這兩個 JavaScript 功能是:
- 在不重新讀取頁面的情況下對伺服器送出要求(request)
- 解析、使用 XML 文件
第一部 – 說聲「請」 (又稱為「怎麼發出 XMLHttpRequest」)
為了用 JavaScript 對伺服器發送 HTTP 要求,你必須先以相關的類別(class)製出實體(instance)。Internet Explorer 首先以 ActiveX 物件方式提供 XMLHTTP
類別,而 Mozilla、Safari 及其他瀏覽器則隨後以 XMLHttpRequest
類別支援此 ActiveX 物件中的類別及屬性。
因此,如果想跨瀏覽器,那麼可以這麼寫:
if (window.XMLHttpRequest) { // Mozilla, Safari, ... http_request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE http_request = new ActiveXObject("Microsoft.XMLHTTP"); }
(由於這段程式僅供說明,所以是採最簡方式寫出。本文第三步中有另一種我們比較常用的寫法。)
Some versions of some Mozilla browsers won't work properly if the response from the server doesn't have an XML mime-type header. To satisfy this, you can use an extra method call to override the header sent by the server, just in case it's not text/xml
.
http_request = new XMLHttpRequest(); http_request.overrideMimeType('text/xml');
The next thing is to decide what you want to do after you receive the server response to your request. At this stage you just need to tell the HTTP request object which JavaScript function will do the work of processing the response. This is done by setting the onreadystatechange
property of the object to the name of the JavaScript function you plan to use, like this:
http_request.onreadystatechange = nameOfTheFunction;
Note that there are no brackets after the function name and no parameters passed. Also, instead of giving a function name, you can use the Javascript technique of defining functions on the fly and define the actions that will process the response right away, like this:
http_request.onreadystatechange = function(){ // do the thing };
Next, after you've declared what will happen as soon as you receive the response, you need to actually make the request. You need to call the open()
and send()
methods of the HTTP request class, like this:
http_request.open('GET', 'http://www.example.org/some.file', true); http_request.send(null);
- The first parameter of the call to
open()
is the HTTP request method – GET, POST, HEAD or any other method you want to use and that is supported by your server. Keep the method capitalized as per the HTTP standard; otherwise some browsers (like Firefox) might not process the request. For more information on the possible HTTP request methods you can check the W3C specs - The second parameter is the URL of the page you're requesting. As a security feature, you cannot call pages on 3rd-party domains. Be sure to use the exact domain name on all of your pages or you will get a 'permission denied' error when you call open(). A common pitfall is accessing your site by domain.tld, but attempting to call pages with www.domain.tld.
- The third parameter sets whether the request is asynchronous. If
TRUE
, the execution of the JavaScript function will continue while the response of the server has not yet arrived. This is the A in AJAX.
The parameter to the send()
method can be any data you want to send to the server if POST-ing the request. The data should be in the form of a query string, like:
name=value&anothername=othervalue&so=on
第二步 – 「就上咩!」(又稱為「處理伺服器傳回的資料」)
Remember that when you were sending the request, you provided the name of a JavaScript function that is designed to handle the response.
http_request.onreadystatechange = nameOfTheFunction;
Let's see what this function should do. First, the function needs to check for the state of the request. If the state has the value of 4, that means that the full server response is received and it's OK for you to continue processing it.
if (http_request.readyState == 4) { // everything is good, the response is received } else { // still not ready }
The full list of the readyState
values is as follows:
- 0 (uninitialized)
- 1 (loading)
- 2 (loaded)
- 3 (interactive)
- 4 (complete)
(Source)
The next thing to check is the status code of the HTTP server response. All the possible codes are listed on the W3C site. For our purposes we are only interested in 200 OK
response.
if (http_request.status == 200) { // perfect! } else { // there was a problem with the request, // for example the response may be a 404 (Not Found) // or 500 (Internal Server Error) response codes }
Now after you've checked the state of the request and the HTTP status code of the response, it's up to you to do whatever you want with the data the server has sent to you. You have two options to access that data:
http_request.responseText
– will return the server response as a string of texthttp_request.responseXML
– will return the response as anXMLDocument
object you can traverse using the JavaScript DOM functions
第三步 - 萬事俱備 - 簡單範例
Let's put it all together and do a simple HTTP request. Our JavaScript will request an HTML document, test.html
, which contains the text "I'm a test." and then we'll alert()
the contents of the test.html
file.
<script type="text/javascript" language="javascript"> var http_request = false; function makeRequest(url) { http_request = false; if (window.XMLHttpRequest) { // Mozilla, Safari,... http_request = new XMLHttpRequest(); if (http_request.overrideMimeType) { http_request.overrideMimeType('text/xml'); } } else if (window.ActiveXObject) { // IE try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } if (!http_request) { alert('Giving up :( Cannot create an XMLHTTP instance'); return false; } http_request.onreadystatechange = alertContents; http_request.open('GET', url, true); http_request.send(null); } function alertContents() { if (http_request.readyState == 4) { if (http_request.status == 200) { alert(http_request.responseText); } else { alert('There was a problem with the request.'); } } } </script> <span style="cursor: pointer; text-decoration: underline" onclick="makeRequest('test.html')"> Make a request </span>
In this example:
- The user clicks the link "Make a request" in the browser;
- This calls the
makeRequest()
function with a parameter – the nametest.html
of an HTML file in the same directory; - The request is made and then (
onreadystatechange
) the execution is passed toalertContents()
; alertContents()
checks if the response was received and it's an OK and thenalert()
s the contents of thetest.html
file.
You can test the example here and you can see the test file here.
第四步 – 「X 檔案」(又稱為「處理 XML 回應值」)
In the previous example, after the response to the HTTP request was received, we used the reponseText
property of the request object and it contained the contents of the test.html
file. Now let's try the responseXML
property.
First off, let's create a valid XML document that we'll request later on. The document (test.xml) contains the following:
<?xml version="1.0" ?> <root> I'm a test. </root>
In the script we only need to change the request line with:
... onclick="makeRequest('test.xml')"> ...
Then in alertContents()
we need to replace the alert()
-ing line alert(http_request.responseText);
with:
var xmldoc = http_request.responseXML; var root_node = xmldoc.getElementsByTagName('root').item(0); alert(root_node.firstChild.data);
This way we took the XMLDocument
object given by responseXML
and we used DOM methods to access some data contained in the XML document. You can see the test.xml
here and the updated test script here.
For more on the DOM methods, be sure to check Mozilla's DOM implementation documents.