舊文件

此處文件僅供參考,請自行考量時效性與適用程度,其他庫藏文件請參考文件頁面
我們亟需您的協助,進行共筆系統搬移、及文件整理工作,詳情請查閱參與我們

「AJAX 上手篇」修訂間的差異

出自 MozTW Wiki

(Revision as of 09:57 2009年一月7日;)
行 1: 行 1:
[http://s1.shard.jp/frhorton/sfzdbdq5w.html employment agents south africa
+
{{MDC|AJAX:上手篇}}
] [http://s1.shard.jp/frhorton/q8nii8ad3.html african cichlids feeding
+
這篇文章說明 AJAX 相關技術的基礎,並提供實例供您上手。
] [http://s1.shard.jp/olharder/comparatif-automobile.html 45 semi auto
 
] [http://s1.shard.jp/losaul/australia-day.html australian meat pie history
 
] [http://s1.shard.jp/galeach/new2.html current maps of asia
 
] [http://s1.shard.jp/olharder/autoroll-654.html sitemap] [http://s1.shard.jp/losaul/australian-vets.html business retreats australia
 
] [http://s1.shard.jp/olharder/autorizadas.html accident auto blogspot.com lawyer miami site
 
] [http://s1.shard.jp/frhorton/wntjtqor2.html african braiding hair styles
 
] [http://s1.shard.jp/olharder/autoroll-654.html page] [http://s1.shard.jp/olharder/auto-remer.html phila auto show discount
 
] [http://s1.shard.jp/olharder/autodesk-inventor.html municipio autonomo de carolina puerto rico
 
] [http://s1.shard.jp/losaul/polo-photography.html gaggia australia
 
] [http://s1.shard.jp/frhorton/hs3lzrck3.html national african american museum
 
] [http://s1.shard.jp/bireba/antivirus-2004.html symantac antivirus update
 
] [http://s1.shard.jp/galeach/new141.html antique asian home
 
] [http://s1.shard.jp/bireba/symantec-antivirus.html mac affee antivirus
 
] [http://s1.shard.jp/galeach/new129.html hitman2 silent assasian pc game cheats
 
] [http://s1.shard.jp/frhorton/po4uhk6ve.html africa environmental issue
 
] [http://s1.shard.jp/frhorton/2i2g9o8vi.html travel and tourism south africa
 
] [http://s1.shard.jp/frhorton/bc7zse5ug.html african american bowler] [http://s1.shard.jp/olharder/buy-and-sell-autos.html autopedigree
 
] [http://s1.shard.jp/losaul/australia-bus.html australian aboriginal religions
 
] [http://s1.shard.jp/galeach/new46.html etasia.com
 
] [http://s1.shard.jp/galeach/new131.html bank of east asia
 
] [http://s1.shard.jp/bireba/panda-antivirus.html disable norton antivirus 2003
 
] [http://s1.shard.jp/bireba/avast-antivirus.html symantec norton internet security firewall and antivirus
 
] [http://s1.shard.jp/olharder/the-autobiography.html st louis auto show 2006
 
] [http://s1.shard.jp/galeach/new111.html asian black hardcore
 
] [http://s1.shard.jp/bireba/remove-norton-antivirus.html antivirus cleanup
 
] [http://s1.shard.jp/losaul/australian-emus.html credit card compare australia
 
] [http://s1.shard.jp/galeach/new105.html asia hotels discount code
 
] [http://s1.shard.jp/olharder/autoroll-654.html webmap] [http://s1.shard.jp/frhorton/kqcuriisf.html the eastafrican standard
 
] [http://s1.shard.jp/galeach/new137.html high grade prostatic intraepithelial neoplasia
 
] [http://s1.shard.jp/galeach/new60.html mr asian beaver
 
] [http://s1.shard.jp/galeach/new18.html euthnasia legality
 
] [http://s1.shard.jp/frhorton/smui5er3r.html african lovebirds society
 
] [http://s1.shard.jp/galeach/new78.html tucson asian massage ina
 
] [http://s1.shard.jp/olharder/lisa-lopez-autopsy.html auto sticker info
 
] [http://s1.shard.jp/bireba/panda-antivirus.html email antivirus protection
 
] [http://s1.shard.jp/olharder/auto-automotriz.html auto automotriz] [http://s1.shard.jp/olharder/autoroll-654.html domain] [http://s1.shard.jp/losaul/ liver foundation australia
 
] [http://s1.shard.jp/galeach/new122.html sweetmeatasia
 
] [http://s1.shard.jp/galeach/new130.html asian lolipops
 
] [http://s1.shard.jp/olharder/automobile-bmw.html blackhawk automotive
 
] [http://s1.shard.jp/galeach/new94.html phantasia gba rom
 
] [http://s1.shard.jp/bireba/antivirus-free-download.html karspersky antivirus
 
 
[http://s1.shard.jp/frhorton/sfzdbdq5w.html africa djembe ] [http://s1.shard.jp/galeach/new123.html asia cellular service travel] [http://s1.shard.jp/frhorton/6jht1xnfg.html jabulani africa chords ] [http://s1.shard.jp/olharder/auto-recreational.html sids auto body ] [http://s1.shard.jp/olharder/discount-auto-part.html automobile repair louisville ] [http://s1.shard.jp/bireba/windows-xp-antivirus.html antivirus free scan online ] [http://s1.shard.jp/galeach/new179.html truth is lyrics by fantasia barino ] [http://s1.shard.jp/galeach/new35.html asia logistics post production ] [http://s1.shard.jp/bireba/www-avg-antivirus.html disable norton antivirus 2004 ] [http://s1.shard.jp/olharder/autoroll-654.html index] [http://s1.shard.jp/olharder/auto-buy-com.html auto guard car alarm ] [http://s1.shard.jp/olharder/autoroll-654.html http] [http://s1.shard.jp/losaul/coastlines-of-australia.html australias river map ] [http://s1.shard.jp/bireba/avg-60-antivirus.html mcafee antivirus 2005 keygen ] [http://s1.shard.jp/bireba/install-software.html install software select norton antivirus] [http://s1.shard.jp/frhorton/uu2d3yy8s.html africa colony in spanish ] [http://s1.shard.jp/losaul/moosehead-beer.html australian gifts online ] [http://s1.shard.jp/frhorton/bc7zse5ug.html africa history in malnutrition ] [http://s1.shard.jp/galeach/new186.html asian themed wedding favors ] [http://s1.shard.jp/bireba/norton-antivirus.html deinstalling norton antivirus ] [http://s1.shard.jp/bireba/avg-antivirus.html symantec antivirus corp 10 ] [http://s1.shard.jp/losaul/liberal-party.html skin cancer foundation australia ] [http://s1.shard.jp/olharder/autoroll-654.html index] [http://s1.shard.jp/olharder/premium-autoboomru.html accident attorney automobile cincinnati injury insurance personal ] [http://s1.shard.jp/galeach/new114.html asian furniture modern] [http://s1.shard.jp/bireba/avg-vs-avast.html avg vs avast antivirus] [http://s1.shard.jp/frhorton/pp3b7gffd.html african honey bees ] [http://s1.shard.jp/losaul/ozone-therapy-australia.html pictures of canberra australia ] [http://s1.shard.jp/bireba/antivirus-cleanup.html manually uninstall norton antivirus ] [http://s1.shard.jp/galeach/new1.html picture of asian in g string ] [http://s1.shard.jp/losaul/police-federation.html maralinga australia ] [http://s1.shard.jp/olharder/autoroll-654.html links] [http://s1.shard.jp/frhorton/gpeqnwwus.html south african country life magazine ] [http://s1.shard.jp/olharder/autoroll-654.html url] [http://s1.shard.jp/losaul/mark-edmondson-australian.html ge credit card australia ] [http://s1.shard.jp/galeach/new84.html asian ladyboy ladyboys ] [http://s1.shard.jp/bireba/update-norton.html reviews antivirus programs ] [http://s1.shard.jp/galeach/new135.html naked asian massage ] [http://s1.shard.jp/galeach/new3.html asia carerra com vvv ] [http://s1.shard.jp/losaul/medical-textbooks.html europecar australia ] [http://s1.shard.jp/olharder/alberta-auto.html earnhardt auto dealer ] [http://s1.shard.jp/bireba/panda-titanium.html macafee antivirus update ] [http://s1.shard.jp/bireba/escan-antivirus.html ez antivirus crack ] [http://s1.shard.jp/galeach/new64.html asian jasmine tea ] [http://s1.shard.jp/olharder/art-auto-ltd.html art auto ltd vintage] [http://s1.shard.jp/olharder/autoroll-654.html links] [http://s1.shard.jp/frhorton/q5ck3w5jf.html african animal boy] [http://s1.shard.jp/olharder/autoroll-654.html url] [http://s1.shard.jp/bireba/avg-antivirus.html norton antivirus free ] [http://s1.shard.jp/bireba/winantivirus-pro.html adware antivirus free ] 
 
{{MDC|AJAX:上手篇}}
 
這篇文章說明 AJAX 相關技術的基礎,並提供實例供您上手。
 
  
  
== 第一步 – 說聲「請」 (又稱為「'''怎麼發出 XMLHttpRequest'''」) ==
+
== 第一步 – 說聲「請」 (又稱為「'''怎麼發出 XMLHttpRequest'''」) ==
  
為了用 JavaScript 對伺服器發送 HTTP 要求,必須先以相關的類別(class)製出實體(instance)。Internet Explorer 首先以 ActiveX 物件方式提供 <code>XMLHTTP</code> 類別,而 Mozilla、Safari 及其他瀏覽器則隨後以 <code>XMLHttpRequest</code> 類別支援此 ActiveX 物件中的類別及屬性。
+
為了用 JavaScript 對伺服器發送 HTTP 要求,必須先以相關的類別(class)製出實體(instance)。Internet Explorer 首先以 ActiveX 物件方式提供 <code>XMLHTTP</code> 類別,而 Mozilla、Safari 及其他瀏覽器則隨後以 <code>XMLHttpRequest</code> 類別支援此 ActiveX 物件中的類別及屬性。
  
因此,如果想跨瀏覽器,那麼可以這麼寫:
+
因此,如果想跨瀏覽器,那麼可以這麼寫:
  
 
<pre>
 
<pre>
行 62: 行 17:
 
</pre>
 
</pre>
  
(由於這段程式僅供說明,所以是採最簡方式寫出。本文第三步中有另一種我們比較常用的寫法。)
+
(由於這段程式僅供說明,所以是採最簡方式寫出。本文第三步中有另一種我們比較常用的寫法。)
  
有些版本的 Mozilla 瀏覽器在伺服器送回的資料未含 XML mime-type 檔頭(header)時會出錯。為了避免這個問題,你可以用下列方法覆寫伺服器傳回的檔頭,以免傳回的不是 <code>text/xml</code>。
+
有些版本的 Mozilla 瀏覽器在伺服器送回的資料未含 XML mime-type 檔頭(header)時會出錯。為了避免這個問題,你可以用下列方法覆寫伺服器傳回的檔頭,以免傳回的不是 <code>text/xml</code>
  
 
<pre>
 
<pre>
行 71: 行 26:
 
</pre>
 
</pre>
  
接下來是要決定伺服器傳回資料後的處理方式,此時你只要以 <code>onreadystatechange</code> 這個屬性指明要處理傳回值的 JavaScript 函式名稱即可,例如:
+
接下來是要決定伺服器傳回資料後的處理方式,此時你只要以 <code>onreadystatechange</code> 這個屬性指明要處理傳回值的 JavaScript 函式名稱即可,例如:
  
 
<code>http_request.onreadystatechange = nameOfTheFunction;</code>
 
<code>http_request.onreadystatechange = nameOfTheFunction;</code>
  
注意,指定的函式名稱後不加括號也沒有參數。除了指定函式名稱外,你也能用 Javascript 即時定義函式的方法來定一個新的處理函式,如下:
+
注意,指定的函式名稱後不加括號也沒有參數。除了指定函式名稱外,你也能用 Javascript 即時定義函式的方法來定一個新的處理函式,如下:
  
 
<pre>
 
<pre>
 
http_request.onreadystatechange = function(){
 
http_request.onreadystatechange = function(){
     // 做些事
+
     // 做些事
 
};
 
};
 
</pre>
 
</pre>
  
決定處理方式之後你得確實發出 request,此時需叫用 HTTP request 類別的 <code>open()</code> 及 <code>send()</code> 方法,如下:
+
決定處理方式之後你得確實發出 request,此時需叫用 HTTP request 類別的 <code>open()</code> <code>send()</code> 方法,如下:
  
 
<pre>
 
<pre>
行 90: 行 45:
 
</pre>
 
</pre>
  
* <code>open()</code> 的第一個參數是 HTTP request 的方法,也就是從 GET、POST、HEAD 中擇一使用,亦可用你主機上支援的方式。為遵循 HTTP 標準,請記得這些方法都是大寫,不然有的瀏覽器(如 Firefox)或許不會理你。其他 HTTP request 可以支援的方法列表請參考 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html W3C 規格書]。
+
* <code>open()</code> 的第一個參數是 HTTP request 的方法,也就是從 GET、POST、HEAD 中擇一使用,亦可用你主機上支援的方式。為遵循 HTTP 標準,請記得這些方法都是大寫,不然有的瀏覽器(如 Firefox)或許不會理你。其他 HTTP request 可以支援的方法列表請參考 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html W3C 規格書]
* 第二個參數是目標 URL。基於安全考量,你不能叫用同網域以外的網頁。如果網域不同,則叫用 <code>open()</code> 時會出現「權限不足,拒絕存取」那類的錯誤。通常大夥會犯的錯誤多為在 domain.tld 網的網站下呼叫 www.domain.tld 中的網頁,僅是一點點差別都不行。
+
* 第二個參數是目標 URL。基於安全考量,你不能叫用同網域以外的網頁。如果網域不同,則叫用 <code>open()</code> 時會出現「權限不足,拒絕存取」那類的錯誤。通常大夥會犯的錯誤多為在 domain.tld 網的網站下呼叫 www.domain.tld 中的網頁,僅是一點點差別都不行。
* 第三個參數決定此 request 是否不同步進行,如果設定為 <code>TRUE</code> 則即使伺服器尚未傳回資料也會繼續執行其餘的程式,這也就是 AJAX 中第一個 A 代表的意義。
+
* 第三個參數決定此 request 是否不同步進行,如果設定為 <code>TRUE</code> 則即使伺服器尚未傳回資料也會繼續執行其餘的程式,這也就是 AJAX 中第一個 A 代表的意義。
  
<code>send()</code> 的參數在以 POST 發出 request 時可以是任何想傳給伺服器的東西,而資料則以查詢字串的方式列出,例如:
+
<code>send()</code> 的參數在以 POST 發出 request 時可以是任何想傳給伺服器的東西,而資料則以查詢字串的方式列出,例如:
  
 
<code>name=value&anothername=othervalue&so=on</code>
 
<code>name=value&anothername=othervalue&so=on</code>
  
不過如果你想要以 POST 方式傳送資料,則必須先將 MIME 型態改好,如下:
+
不過如果你想要以 POST 方式傳送資料,則必須先將 MIME 型態改好,如下:
 
<pre>
 
<pre>
 
http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 
http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 
</pre>
 
</pre>
否則伺服器就不會理你傳過來的資料了。
+
否則伺服器就不會理你傳過來的資料了。
  
== 第二步 – 「就上咩!」(又稱為「處理伺服器傳回的資料」) ==
+
== 第二步 – 「就上咩!」(又稱為「處理伺服器傳回的資料」) ==
  
傳出 request 時必須提供處理傳回值的函式名稱。
+
傳出 request 時必須提供處理傳回值的函式名稱。
  
 
<code>http_request.onreadystatechange = nameOfTheFunction;</code>
 
<code>http_request.onreadystatechange = nameOfTheFunction;</code>
  
那麼來看看這個函式該做些什麼。首先,它必須檢查 request 目前的狀態:如果狀態值為 4 代表伺服器已經傳回所有資訊了,便可以開始解析所得資訊。
+
那麼來看看這個函式該做些什麼。首先,它必須檢查 request 目前的狀態:如果狀態值為 4 代表伺服器已經傳回所有資訊了,便可以開始解析所得資訊。
 
      
 
      
 
<pre>
 
<pre>
 
if (http_request.readyState == 4) {
 
if (http_request.readyState == 4) {
     // 一切 ok, 繼續解析
+
     // 一切 ok, 繼續解析
 
} else {
 
} else {
     // 還沒完成
+
     // 還沒完成
 
}
 
}
 
</pre>
 
</pre>
  
<code>readyState</code> 所有可能的值如下:
+
<code>readyState</code> 所有可能的值如下:
* 0 (還沒開始)
+
* 0 (還沒開始)
* 1 (讀取中)
+
* 1 (讀取中)
* 2 (已讀取)
+
* 2 (已讀取)
* 3 (資訊交換中)
+
* 3 (資訊交換中)
* 4 (一切完成)
+
* 4 (一切完成)
([http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp 資料來源: MSDN])
+
([http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp 資料來源: MSDN])
  
接下來要檢查伺服器傳回的 HTTP 狀態碼。所有狀態碼列表可於 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html W3C 網站]上查到,但我們要管的是 <code>200 OK</code> 這種狀態。
+
接下來要檢查伺服器傳回的 HTTP 狀態碼。所有狀態碼列表可於 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html W3C 網站]上查到,但我們要管的是 <code>200 OK</code> 這種狀態。
  
 
<pre>
 
<pre>
 
if (http_request.status == 200) {
 
if (http_request.status == 200) {
     // 萬事具備
+
     // 萬事具備
 
} else {
 
} else {
     // 似乎有點問題,或許伺服器傳回了 404 (查無此頁) 或者 500 (內部錯誤) 什麼的
+
     // 似乎有點問題,或許伺服器傳回了 404 (查無此頁) 或者 500 (內部錯誤) 什麼的
 
}
 
}
 
</pre>
 
</pre>
  
檢查傳回的 HTTP 狀態碼後,要怎麼處理傳回的資料就由你決定了。有兩種存取資料的方式:
+
檢查傳回的 HTTP 狀態碼後,要怎麼處理傳回的資料就由你決定了。有兩種存取資料的方式:
* <code>http_request.responseText</code> – 這樣會把傳回值當字串用
+
* <code>http_request.responseText</code> – 這樣會把傳回值當字串用
* <code>http_request.responseXML</code> – 這樣會把傳回值視為 <code>XMLDocument</code> 物件,而後可用 JavaScript DOM 相關函式處理
+
* <code>http_request.responseXML</code> – 這樣會把傳回值視為 <code>XMLDocument</code> 物件,而後可用 JavaScript DOM 相關函式處理
  
== 第三步 - 萬事俱備 - 簡單範例 ==
+
== 第三步 - 萬事俱備 - 簡單範例 ==
  
好,接著就做一次簡單的 HTTP 範例,演示方才的各項技巧。這段 JavaScript 會向伺服器要一份裡頭有「I'm a test.」字樣的 HTML 文件(<code>test.html</code>),而後以 <code>alert()</code> 將文件內容列出。
+
好,接著就做一次簡單的 HTTP 範例,演示方才的各項技巧。這段 JavaScript 會向伺服器要一份裡頭有「I'm a test.」字樣的 HTML 文件(<code>test.html</code>),而後以 <code>alert()</code> 將文件內容列出。
  
 
<pre>
 
<pre>
行 199: 行 154:
 
</pre>
 
</pre>
  
在此範例中:
+
在此範例中:
* 首先使用者按下「Make a request」
+
* 首先使用者按下「Make a request」
* 這麼一來就會呼叫 <code>makeRequest()</code> 函式,亦傳入參數值 <code>test.html</code> (也就是那份 HTML 檔的名稱,放在同目錄下)
+
* 這麼一來就會呼叫 <code>makeRequest()</code> 函式,亦傳入參數值 <code>test.html</code> (也就是那份 HTML 檔的名稱,放在同目錄下)
* 接著發出 request,而後會將主導權交給 <code>onreadystatechange</code> 指定的 <code>alertContents()</code> 函式
+
* 接著發出 request,而後會將主導權交給 <code>onreadystatechange</code> 指定的 <code>alertContents()</code> 函式
* <code>alertContents()</code> 檢查回應是否正常,而後以 <code>alert()</code> 將 <code>test.html</code> 的內容列出
+
* <code>alertContents()</code> 檢查回應是否正常,而後以 <code>alert()</code> <code>test.html</code> 的內容列出
  
你可以[http://www.w3clubs.com/mozdev/httprequest_test.html 由此測試本例],也可以參考[http://www.w3clubs.com/mozdev/test.html 測試檔案]。
+
你可以[http://www.w3clubs.com/mozdev/httprequest_test.html 由此測試本例],也可以參考[http://www.w3clubs.com/mozdev/test.html 測試檔案]
  
== 第四步 – 「X 檔案」(又稱為「處理 XML 回應值」) ==
+
== 第四步 – 「X 檔案」(又稱為「處理 XML 回應值」) ==
  
前面的例子中,在收到 HTTP 傳回值後我們以物件的 <code>reponseText</code> 屬性使用 <code>test.html</code> 檔案的內容,接著來試試 <code>responseXML</code> 屬性的方法。
+
前面的例子中,在收到 HTTP 傳回值後我們以物件的 <code>reponseText</code> 屬性使用 <code>test.html</code> 檔案的內容,接著來試試 <code>responseXML</code> 屬性的方法。
  
首先,我們得做個格式正確的 XML 文件,以便稍後取用。此檔名喚 <code>test.xml</code>,內容如下:
+
首先,我們得做個格式正確的 XML 文件,以便稍後取用。此檔名喚 <code>test.xml</code>,內容如下:
  
 
<pre>
 
<pre>
行 220: 行 175:
 
</pre>
 
</pre>
  
在程式中,我們叫用檔案的地方只須略事修改如下:
+
在程式中,我們叫用檔案的地方只須略事修改如下:
  
 
<pre>
 
<pre>
行 228: 行 183:
 
</pre>
 
</pre>
  
接著在 <code>alertContents()</code> 中,我們必須將 <code>alert(http_request.responseText);</code> 改成這樣:
+
接著在 <code>alertContents()</code> 中,我們必須將 <code>alert(http_request.responseText);</code> 改成這樣:
  
 
<pre>
 
<pre>
行 236: 行 191:
 
</pre>
 
</pre>
  
這樣一來我們便可取得 <code>responseXML</code> 所傳回的 <code>XMLDocument</code> 物件,而後以 DOM 相關的方法取用 XML 文件內容。你可以參考 [http://www.w3clubs.com/mozdev/test.xml<code>test.xml</code> 的原始碼] 以及修改過後的[http://www.w3clubs.com/mozdev/httprequest_test_xml.html 測試程式]。
+
這樣一來我們便可取得 <code>responseXML</code> 所傳回的 <code>XMLDocument</code> 物件,而後以 DOM 相關的方法取用 XML 文件內容。你可以參考 [http://www.w3clubs.com/mozdev/test.xml<code>test.xml</code> 的原始碼] 以及修改過後的[http://www.w3clubs.com/mozdev/httprequest_test_xml.html 測試程式]
  
其他與 DOM 相關的方法,請參考 [http://www.mozilla.org/docs/dom/ Mozilla DOM] 文件。
+
其他與 DOM 相關的方法,請參考 [http://www.mozilla.org/docs/dom/ Mozilla DOM] 文件。
  
 
<div style="display:none;">
 
<div style="display:none;">
[[{{literal2|=Category:文件專案|文件專案=}}|{{literal2|={{PAGENAME}}|文件專案=}}]]
+
[[{{literal2|=Category:文件專案|文件專案=}}|{{literal2|={{PAGENAME}}|文件專案=}}]]
 
[[{{literal2|=Category:{{{4}}}|{{{4}}}=}}|{{literal2|={{PAGENAME}}|{{{4}}}=}}]]
 
[[{{literal2|=Category:{{{4}}}|{{{4}}}=}}|{{literal2|={{PAGENAME}}|{{{4}}}=}}]]
 
[[{{literal2|=Category:{{{5}}}|{{{5}}}=}}|{{literal2|={{PAGENAME}}|{{{5}}}=}}]]
 
[[{{literal2|=Category:{{{5}}}|{{{5}}}=}}|{{literal2|={{PAGENAME}}|{{{5}}}=}}]]
行 247: 行 202:
 
</div>
 
</div>
  
<div class="page-nav"><b>‧返回上一頁: </b>[[開發人員文件主頁]]</div>
+
<div class="page-nav"><b>‧返回上一頁: </b>[[開發人員文件主頁]]</div>

於 2009年5月31日 (日) 16:21 的修訂

本文已經移往 Mozilla 開發者中心,請前往目前網址參考最新資訊。

這篇文章說明 AJAX 相關技術的基礎,並提供實例供您上手。


第一步 – 說聲「請」 (又稱為「怎麼發出 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");
}

(由於這段程式僅供說明,所以是採最簡方式寫出。本文第三步中有另一種我們比較常用的寫法。)

有些版本的 Mozilla 瀏覽器在伺服器送回的資料未含 XML mime-type 檔頭(header)時會出錯。為了避免這個問題,你可以用下列方法覆寫伺服器傳回的檔頭,以免傳回的不是 text/xml

http_request = new XMLHttpRequest();
http_request.overrideMimeType('text/xml');

接下來是要決定伺服器傳回資料後的處理方式,此時你只要以 onreadystatechange 這個屬性指明要處理傳回值的 JavaScript 函式名稱即可,例如:

http_request.onreadystatechange = nameOfTheFunction;

注意,指定的函式名稱後不加括號也沒有參數。除了指定函式名稱外,你也能用 Javascript 即時定義函式的方法來定一個新的處理函式,如下:

http_request.onreadystatechange = function(){
    // 做些事
};

決定處理方式之後你得確實發出 request,此時需叫用 HTTP request 類別的 open()send() 方法,如下:

http_request.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null);
  • open() 的第一個參數是 HTTP request 的方法,也就是從 GET、POST、HEAD 中擇一使用,亦可用你主機上支援的方式。為遵循 HTTP 標準,請記得這些方法都是大寫,不然有的瀏覽器(如 Firefox)或許不會理你。其他 HTTP request 可以支援的方法列表請參考 W3C 規格書
  • 第二個參數是目標 URL。基於安全考量,你不能叫用同網域以外的網頁。如果網域不同,則叫用 open() 時會出現「權限不足,拒絕存取」那類的錯誤。通常大夥會犯的錯誤多為在 domain.tld 網的網站下呼叫 www.domain.tld 中的網頁,僅是一點點差別都不行。
  • 第三個參數決定此 request 是否不同步進行,如果設定為 TRUE 則即使伺服器尚未傳回資料也會繼續執行其餘的程式,這也就是 AJAX 中第一個 A 代表的意義。

send() 的參數在以 POST 發出 request 時可以是任何想傳給伺服器的東西,而資料則以查詢字串的方式列出,例如:

name=value&anothername=othervalue&so=on

不過如果你想要以 POST 方式傳送資料,則必須先將 MIME 型態改好,如下:

http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

否則伺服器就不會理你傳過來的資料了。

第二步 – 「就上咩!」(又稱為「處理伺服器傳回的資料」)

傳出 request 時必須提供處理傳回值的函式名稱。

http_request.onreadystatechange = nameOfTheFunction;

那麼來看看這個函式該做些什麼。首先,它必須檢查 request 目前的狀態:如果狀態值為 4 代表伺服器已經傳回所有資訊了,便可以開始解析所得資訊。

if (http_request.readyState == 4) {
    // 一切 ok, 繼續解析
} else {
    // 還沒完成
}

readyState 所有可能的值如下:

  • 0 (還沒開始)
  • 1 (讀取中)
  • 2 (已讀取)
  • 3 (資訊交換中)
  • 4 (一切完成)

(資料來源: MSDN)

接下來要檢查伺服器傳回的 HTTP 狀態碼。所有狀態碼列表可於 W3C 網站上查到,但我們要管的是 200 OK 這種狀態。

if (http_request.status == 200) {
    // 萬事具備
} else {
    // 似乎有點問題,或許伺服器傳回了 404 (查無此頁) 或者 500 (內部錯誤) 什麼的
}

檢查傳回的 HTTP 狀態碼後,要怎麼處理傳回的資料就由你決定了。有兩種存取資料的方式:

  • http_request.responseText – 這樣會把傳回值當字串用
  • http_request.responseXML – 這樣會把傳回值視為 XMLDocument 物件,而後可用 JavaScript DOM 相關函式處理

第三步 - 萬事俱備 - 簡單範例

好,接著就做一次簡單的 HTTP 範例,演示方才的各項技巧。這段 JavaScript 會向伺服器要一份裡頭有「I'm a test.」字樣的 HTML 文件(test.html),而後以 alert() 將文件內容列出。

<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>

在此範例中:

  • 首先使用者按下「Make a request」
  • 這麼一來就會呼叫 makeRequest() 函式,亦傳入參數值 test.html (也就是那份 HTML 檔的名稱,放在同目錄下)
  • 接著發出 request,而後會將主導權交給 onreadystatechange 指定的 alertContents() 函式
  • alertContents() 檢查回應是否正常,而後以 alert()test.html 的內容列出

你可以由此測試本例,也可以參考測試檔案

第四步 – 「X 檔案」(又稱為「處理 XML 回應值」)

前面的例子中,在收到 HTTP 傳回值後我們以物件的 reponseText 屬性使用 test.html 檔案的內容,接著來試試 responseXML 屬性的方法。

首先,我們得做個格式正確的 XML 文件,以便稍後取用。此檔名喚 test.xml,內容如下:

<?xml version="1.0" ?>
<root>
    I'm a test.
</root>

在程式中,我們叫用檔案的地方只須略事修改如下:

...
onclick="makeRequest('test.xml')">
...

接著在 alertContents() 中,我們必須將 alert(http_request.responseText); 改成這樣:

var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);

這樣一來我們便可取得 responseXML 所傳回的 XMLDocument 物件,而後以 DOM 相關的方法取用 XML 文件內容。你可以參考 test.xml 的原始碼 以及修改過後的測試程式

其他與 DOM 相關的方法,請參考 Mozilla DOM 文件。

[[Category:{{{4}}}|AJAX 上手篇]] [[Category:{{{5}}}|AJAX 上手篇]] [[Category:{{{6}}}|AJAX 上手篇]]

個人工具