在過去幾年,JavaScript 已從讓人事后才想起的偶然對(duì)象變成最重要的 Web 語言。如果要指出一個(gè)推動(dòng)這項(xiàng)技術(shù)顯著進(jìn)步的因素,那就是基于 Ajax 的應(yīng)用程序開發(fā)的出現(xiàn)。
開發(fā)關(guān)于該主題的技術(shù)
簡言之,Ajax 是一種開發(fā)技術(shù),支持網(wǎng)站或應(yīng)用程序,使用實(shí)時(shí)數(shù)據(jù)更新界面,無需頁面刷新。該功能創(chuàng)建了一種更為流暢且更具桌面風(fēng)格的用戶體驗(yàn)。
Ajax 簡史
Ajax 的發(fā)展歷史類似于其他許多一夜成名的技術(shù)。盡管 Ajax 似乎不知從何而來,但實(shí)際上,它已經(jīng)存在很長一段時(shí)間了。多年的努力使其遍布 Web,在 Ajax 旗幟的帶領(lǐng)下創(chuàng)建工具和模式??v觀最初網(wǎng)絡(luò)泡沫的 DHTML 時(shí)代,以及網(wǎng)絡(luò)公司破產(chǎn)后的黑暗年代,世界各地的開發(fā)人員解禁了 JavaScript 的超能力,將這個(gè)嶄新的、令人激動(dòng)的應(yīng)用程序模式引人 Web。
XMLHttpRequest
最早最重要的 Ajax 謎題是 XMLHttpRequest (XHR) API。XHR 是一種用于在 Web 瀏覽器和 Web 服務(wù)器間傳輸數(shù)據(jù)消息的 JavaScript API。它支持瀏覽器使用 HTTP POST(將數(shù)據(jù)傳到服務(wù)器)或 GET 請(qǐng)求(從后臺(tái)服務(wù)器訪問數(shù)據(jù))。該 API 是大多數(shù) Ajax 交互的核心,也是現(xiàn)代 Web 開發(fā)的一項(xiàng)基本技術(shù)。
它也是 Microsoft® Internet Explorer® 團(tuán)隊(duì)貢獻(xiàn)給 Internet 的最好禮物。
這是真的。早在 2000 年,XHR 最先出現(xiàn)于 IE 5 中。最初是由 Alex Hopmann 編寫的 Microsoft ® ActiveX® 控件,創(chuàng)建 XHR 是為了處理 Microsoft Outlook® Web Access,旨在解決高級(jí)(當(dāng)時(shí))前端接口和 Microsoft Exchange Server 間的交互。
盡管 Microsoft 的軟件包不完全算是 “出身貧賤”,但 XHR 的發(fā)展遠(yuǎn)遠(yuǎn)超出了最初產(chǎn)品的范圍,后來在各個(gè)主要瀏覽器中得以實(shí)現(xiàn),甚至作為一種 W3C 標(biāo)準(zhǔn)被采用。
先鋒
除了 Microsoft 之外,還有其他一些企業(yè)開始進(jìn)軍原型 Ajax 領(lǐng)域。許多企業(yè)都開始嘗試使用這些技術(shù),其中有兩個(gè)特別值得一提 — 一個(gè)是因?yàn)樗且粋€(gè)有趣且經(jīng)常引用的 Ajax 開發(fā)腳注,另一個(gè)是因?yàn)樗钦嬲龑⑦@些技術(shù)大眾化的 Internet 巨頭。
Oddpost
Oddpost 是 2002 年推出的基于 Web 的高級(jí)郵件客戶端。它利用許多目前人們所熟知的模式。在設(shè)計(jì)和交互方面,人們會(huì)想起桌面郵件客戶端。在系統(tǒng)內(nèi)部,Oddpost 使用開發(fā)人員稱為 DataPacks 的概念將小塊數(shù)據(jù)從服務(wù)器傳輸?shù)綖g覽器。這將帶來一種全新體驗(yàn)。
Oddpost 最后被 Yahoo!收購,成為 Yahoo! Mail 修訂版的基礎(chǔ)。
Google Maps、Google Suggest、Gmail 以及一篇重要文章
真正的變化開始于幾年后的 Gmail、Google Suggest 和 Google Maps 服務(wù)。這三項(xiàng) Ajax 技術(shù)的使用使得 Web 開發(fā)界沸騰起來。它的響應(yīng)能力和交互性對(duì)公眾而言是全新的。新的 Google 應(yīng)用程序很快引起了轟動(dòng)。
雖然了解它的人并不是很多,但 Web 開發(fā)界對(duì)此反響非常劇烈。當(dāng)時(shí),人們知道在 Web 應(yīng)用程序開發(fā)中出現(xiàn)了一些新的、激動(dòng)人心的內(nèi)容。但在很長一段時(shí)期內(nèi),這個(gè) “內(nèi)容” 一度模糊不清。
人們需要的是一篇讓該內(nèi)容明朗化的文章。
2005 年 2 月 18 日,Adaptive Path 的共同創(chuàng)立者兼總裁 Jesse James Garrett 撰寫了一篇題為 “Ajax: A New Approach to Web Applications” 的文章。在這篇文章中,他介紹了 Web 應(yīng)用程序設(shè)計(jì)開發(fā)的趨勢,諸如 Gmail 和 Google Maps 這類應(yīng)用程序人們一直都在使用。他稱這種趨勢為 “可能引發(fā) Web 開發(fā)的根本性變革?!?br />
他還為這種模式命名,這是一個(gè)重要的時(shí)刻,因?yàn)閺倪@一刻起人們開始重點(diǎn)關(guān)注這一新趨勢,每個(gè)人(甚至是非專業(yè)人員)在談及 Web 開發(fā)界近期最新變化時(shí)都會(huì)提到它。在本文中,他是這樣介紹 Ajax 這種技術(shù)的:
定義 Ajax
Ajax 不是一種技術(shù)。實(shí)際上是幾種技術(shù),每種技術(shù)都各有其特色,這些技術(shù)以全新強(qiáng)大方式融合在一起。Ajax 包含:
- 使用 XHTML 和 CSS 基于標(biāo)準(zhǔn)的呈現(xiàn)
- 使用文檔對(duì)象模型的動(dòng)態(tài)顯示和交互
- 使用 XML 和 XSLT 的數(shù)據(jù)交換和操作
- 使用 XMLHttpRequest 的異步數(shù)據(jù)檢索
- 將它們綁定到一起的 JavaScript
雖然這個(gè)技術(shù)說明從某種程度上講有些過時(shí)了,但基本模式依然是完整的:HTML 和 CSS 呈現(xiàn)數(shù)據(jù)和樣式,DOM 和相關(guān)方法支持頁面實(shí)時(shí)更新,XHR 支持與服務(wù)器通信,JavaScript 安排整體顯示。
本文的總體影響比較大。密集的大肆宣傳與亟待開發(fā)的創(chuàng)造力和能源相碰撞,掀起了一場革命,這實(shí)屬難得一見。由于 Ajax 被世界范圍的新一代創(chuàng)業(yè)企業(yè)所采用,它迅速走向 Web 開發(fā)范式的前沿。Ajax 從一個(gè)尋求市場策略的模糊趨勢一躍成為現(xiàn)代Web 設(shè)計(jì)的開發(fā)的關(guān)鍵組成部分。
庫
基于 Ajax 開發(fā)的一個(gè)關(guān)鍵驅(qū)動(dòng)因素是幾個(gè)全功能 JavaScript 庫的演變和改進(jìn)。除了經(jīng)驗(yàn)豐富的 JavaScript 開發(fā)人員,很少有人能夠真正理解 Ajax 底層技術(shù)。因此,即使在 DHTML 時(shí)代,雖然研究出了大部分瀏覽器交互和動(dòng)畫來應(yīng)對(duì)瑣碎的超額,但數(shù)量有限的幾個(gè)經(jīng)驗(yàn)豐富的 JavaScript 工程師導(dǎo)致基于 Ajax 的站點(diǎn)需求和人才(他們可以從零開始編寫這樣一個(gè)界面)供應(yīng)之間的差距的進(jìn)一步擴(kuò)大。通過提供隨時(shí)可用的交互和動(dòng)畫,減少跨瀏覽器差異和改進(jìn)核心 JavaScript API 缺點(diǎn)的實(shí)現(xiàn),Prototype、Dojo 和 jQuery 這類庫有助于大規(guī)模地填補(bǔ)這一空白。
異步 JavaScript 以及更多 JavaScript(對(duì)象表示法)
從原始 post 時(shí)代到現(xiàn)代,Ajax 領(lǐng)域的最大改變是引入了 JSON,JSON 是一種基于 JavaScript 的數(shù)據(jù)傳輸。提供更小的文件和更便利的原生 JavaScript 訪問(與 XML 使用的笨重的基于 DOM 的方法和屬性截然相反),JSON 很快就被開發(fā)人員用于進(jìn)行數(shù)據(jù)傳輸。現(xiàn)在 JSON 已列入近期完成的 ECMAScript 規(guī)范的第 5 版。
JSON+Padding
原始 JSON 提議的一個(gè)顯著增強(qiáng)是 JSON+Padding (JSONP)。正如您所看到的,XMLHttpRequest 對(duì)象有一個(gè)嚴(yán)格的安全模型,只支持使用與請(qǐng)求頁面相同的域名和協(xié)議進(jìn)行通信。JSONP 在這個(gè)跨域限制上創(chuàng)建了一種更為靈活的方法,將 JSON 響應(yīng)包裝到一個(gè)用戶定義或系統(tǒng)提供的回調(diào)函數(shù)中。將 JSON 腳本添加到文檔之后,該方法將會(huì)提供即時(shí)數(shù)據(jù)訪問。該模式現(xiàn)在很常見,對(duì)于許多較大的 Web 服務(wù),可以采用該實(shí)踐來支持混搭應(yīng)用和其他內(nèi)容聯(lián)合。
盡管 JSONP 非常流行,但它有一個(gè)明顯的便于惡意代碼入侵的漏洞。因?yàn)閬碜缘谌降哪_本標(biāo)記注入允許所有內(nèi)容在主機(jī)頁面上運(yùn)行,所以,在數(shù)據(jù)提供者受到威脅時(shí),或者主機(jī)頁面沒有留意插入頁面的資源時(shí),惡意入侵潛能將會(huì)令人想象。
現(xiàn)在,您已經(jīng)對(duì) Ajax 歷史有所了解,接下來我們將開始探討將魔法變成現(xiàn)實(shí)的技術(shù)。盡管,一般的 JavaScript API 書籍在圖書館中隨處可見,但即使對(duì)于經(jīng)驗(yàn)豐富的開發(fā)人員,了解底層工作原理仍然是具有啟發(fā)意義的。
XMLHttpRequest API 和特性
盡管可以使用其他技術(shù)從服務(wù)器中返回?cái)?shù)據(jù),但是 XHR 仍然是大多數(shù) Ajax 交互的核心。XHR 交互由兩部分組成:請(qǐng)求和響應(yīng)。下面我們將逐個(gè)介紹。
安全模型
正如上面所提到的,原始 XMLHttpRequest 對(duì)象有一個(gè)嚴(yán)格的安全模型。這個(gè)同源策略只 允許使用與請(qǐng)求頁面相同的主機(jī)、協(xié)議和端口進(jìn)行通信。這意味著不同域(example.com 和 example2.com)、不同主機(jī)(my.example.com 和 www.example.com)、不同協(xié)議(http://example.com 和 https://example.com)之間的通信是禁止的,這會(huì)產(chǎn)生錯(cuò)誤消息。
隨著第二版 XHR 對(duì)象的開發(fā),新的跨域請(qǐng)求協(xié)議工作將在 W3C 中完成,大量實(shí)現(xiàn)工作由瀏覽器供應(yīng)商完成,針對(duì)跨域請(qǐng)求的機(jī)制目前僅在 Internet Explorer 8+、Mozilla Firefox 3.5+、Apple Safari 4+ 以及 Google Chrome 中提供。盡管發(fā)展已經(jīng)放緩,但仍在請(qǐng)求中發(fā)送了一個(gè)特定 “Origin” 報(bào)頭:
Origin: http://example.com
并將服務(wù)器配置為發(fā)送回一個(gè)匹配的 “Access-Control-Allow-Origin” 報(bào)頭:
Access-Control-Allow-Origin: :http://example.com
現(xiàn)在,可以使用 XHR 對(duì)象跨域進(jìn)行雙向通信了。
請(qǐng)求
請(qǐng)求端有 4 種方法:
- open() 發(fā)起服務(wù)器連接??梢詭?shù):
- method。將要使用的 HTTP 方法(可以是 POST 或者 GET)
- url。請(qǐng)求的 URL
- async。 可選布爾參數(shù),表明請(qǐng)求是否異步(該參數(shù)的默認(rèn)值為 Ture)
- user。一個(gè)可選用戶名,供認(rèn)證使用
- password。一個(gè)可選密碼,供認(rèn)證使用
- setRequestHeader() 設(shè)置請(qǐng)求報(bào)頭,帶有兩個(gè)參數(shù):報(bào)頭及其相關(guān)值
- send() 發(fā)送請(qǐng)求。該方法帶有一個(gè)可選參數(shù),包含 POST 請(qǐng)求的正文
- abort() 中止請(qǐng)求
響應(yīng)
響應(yīng)也有幾個(gè)屬性和方法:
- status。請(qǐng)求的標(biāo)準(zhǔn) HTTP 狀態(tài)(例如,成功請(qǐng)求將返回 200)
- statusText。包括 Web 服務(wù)器返回的完整響應(yīng)字符串,其中包括響應(yīng)文本(例如,304 Not Modified)
- getResponseHeader()。返回特定報(bào)頭內(nèi)容;請(qǐng)求報(bào)頭名稱是其惟一參數(shù)
- getAllResponseHeaders()。返回所有響應(yīng)報(bào)頭的文本
- responseText。響應(yīng)文本的字符串表示
- responseXML。響應(yīng)文本的 XML 表示,一個(gè)包含 DOM 和所有相關(guān) DOM 方法的文檔片段
readyState
實(shí)例化完成后,XMLHttpRequest 對(duì)象有 5 種狀態(tài),使用以下值表示:
- 0: UNSENT。表示對(duì)象已創(chuàng)建
- 1: OPENED。表示 open() 方法已成功調(diào)用
- 2: HEADERS_RECEIVED。表示來自請(qǐng)求的報(bào)頭已收到
- 3: LOADING。表示響應(yīng)報(bào)頭已下載
- 4: DONE。表示請(qǐng)求完成,但是并沒有指出請(qǐng)求是否成功或返回預(yù)期值(查詢響應(yīng)和標(biāo)準(zhǔn) HTTP 報(bào)頭來估量請(qǐng)求的健康狀況)
一個(gè)通用 JavaScript 示例
在我們進(jìn)一步介紹流行庫之前,先通過幾個(gè)原始的 JavaScript 示例來了解正在運(yùn)用的核心技術(shù)。
樣例 HTML 文檔
!doctype html>
html lang="en">
head>
meta charset="utf-8">
title>Simple Ajax Example/title>
meta name="author" content="Rob Larsen">
meta name="viewport" content="width=device-width, initial-scale=1.0">
link rel="stylesheet" href="_assets/css/style.css" rel="external nofollow" >
/head>
body>
div id="main">
h1>Simple Ajax Example/h1>
p>strong id="activate">Click here/strong>
and content will be appended after this paragraph/p>
/div>
script src="_assets/js/ajax.js">/script>
/body>
/html>
下面舉例說明了一個(gè)簡單 GET 請(qǐng)求,該請(qǐng)求將處理 responseXML。這是該技術(shù)發(fā)展早期的典型 Ajax 交互。它可以在所有現(xiàn)代瀏覽器以及 Internet Explorer 7 和 8 中運(yùn)行。
一個(gè)基本 Ajax 函數(shù)
/*
Here's a basic Ajax function
*/
var ajax = function( opts ) {
/*
We have an options argument.
In addition, we want to have some smart defaults.
*/
opts = {
//Is it a Get or Post
type: opts.type || "POST",
//What URL are we going to hit?
url: opts.url || "",
//What do we do with the data
onSuccess: opts.onSuccess || function(){},
//what kind of data do we expect?
data: opts.data || "xml"
};
//create a new XMLHttpRequest
var xhr = new XMLHttpRequest();
//Open the connection to the server
xhr.open(opts.type, opts.url, true);
/*
When the ready state changes
fire this function
*/
xhr.onreadystatechange = function(){
//readyState 4 is "done"
if ( xhr.readyState == 4 ) {
/*
do some simple data processing
There are two components to the returned object-
responseXML and responseText.
Depending on what we're doing we'll need one or the other.
*/
switch (opts.data){
case "json":
//json is text
opts.onSuccess(xhr.responseText);
break;
case "xml":
//XML retains the structure/DOM
//It's passed in whole.
opts.onSuccess(xhr.responseXML);
break;
default :
//Everything else will get TXT
opts.onSuccess(xhr.responseText);;
}
}
};
//close the connection
xhr.send(null);
}
//here's our simple function
var ajaxSample = function(e){
//Simple callback adds some text to the page
var callback = function( data ) {
document.getElementById("main").innerHTML +=
"p>"
+data.getElementsByTagName("data")[0].getAttribute("value")
+"/p>";
}
//And here's our Ajax call
ajax({
type: "GET",
url: "_assets/data/ajax-1.xml",
onSuccess: callback,
data : "xml"
})
//prevent the default action
e.preventDefault();
}
//Wire everything up
document.getElementById("activate").addEventListener("click", ajaxSample, false);
在下面的例子 中可以看到活動(dòng)的原始 ActiveX 對(duì)象。如果沒有本機(jī)實(shí)現(xiàn),可以在不同版本的 Internet Explorer 中使用 Try... Catch 塊來循環(huán)遍歷對(duì)象的潛在引用。這個(gè)完整的跨瀏覽器實(shí)現(xiàn)與 Internet Explorer 是兼容的,甚至可以與古老的 Internet Explorer 5 兼容。
一個(gè)跨瀏覽器 Ajax 腳本
var ajax = function( opts ) {
opts = {
type: opts.type || "POST",
url: opts.url || "",
onSuccess: opts.onSuccess || function(){},
data: opts.data || "xml"
};
/*
Support for the original ActiveX object in older versions of Internet Explorer
This works all the way back to IE5.
*/
if ( typeof XMLHttpRequest == "undefined" ) {
XMLHttpRequest = function () {
try {
return new ActiveXObject("Msxml2.XMLHTTP.6.0");
}
catch (e) {}
try {
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
}
catch (e) {}
try {
return new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {}
throw new Error("No XMLHttpRequest.");
};
}
var xhr = new XMLHttpRequest();
xhr.open(opts.type, opts.url, true);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
switch (opts.data){
case "json":
opts.onSuccess(xhr.responseText);
break;
case "xml":
opts.onSuccess(xhr.responseXML);
break;
default :
opts.onSuccess(xhr.responseText);;
}
}
};
xhr.send(null);
}
var ajaxSample = function(e){
var callback = function( data ) {
document.getElementById("main").innerHTML += "p>"
+data.getElementsByTagName("data")[0].getAttribute("value")
+"/p>";
}
ajax({
type: "GET",
url: "_assets/data/ajax-1.xml",
onSuccess: callback,
data: "xml"
})
e.preventDefault();
}
document.getElementById("activate").addEventListener("click", ajaxSample, false);
下面展示了現(xiàn)今更為常見的模式:采用 JSON 格式的 responseText,并將其解析成本機(jī)的 JavaScript 對(duì)象。這段代碼演示了一個(gè)較為簡單的 JSON 數(shù)據(jù)處理方法。為什么眾多開發(fā)人員都選擇使用 JSON 來傳輸數(shù)據(jù),將該清單與操作 XML 數(shù)據(jù)所需的偶爾間接且冗長的方法進(jìn)行比較,答案顯而易見。
使用 JSON
var ajax = function( opts ) {
opts = {
type: opts.type || "POST",
url: opts.url || "",
onSuccess: opts.onSuccess || function(){},
data: opts.data || "xml"
};
var xhr = new XMLHttpRequest();
xhr.open(opts.type, opts.url, true);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
switch (opt.sdata){
case "json":
opt.onSuccess(xhr.responseText);
break;
case "xml":
opt.onSuccess(xhr.responseXML);
break;
default :
opt.onSuccess(xhr.responseText);;
}
}
};
xhr.send(null);
}
var jsonSample = function(e){
var callback = function( data ) {
//here, the data is actually a string
//we use JSON.parse to turn it into an object
data = JSON.parse(data);
/*
we can then use regular JavaScript object references
to get at our data.
*/
document.getElementById("main").innerHTML += "p>"
+ data.sample.txt
+"/p>";
}
ajax({
type: "GET",
url: "_assets/data/json-1.json",
onSuccess: callback,
data : "json"
})
e.preventDefault();
}
document.getElementById("activate").addEventListener("click", jsonSample, false);
下面例子都使用了 JSON 數(shù)據(jù)。
提供了一個(gè)簡單的 JSONP 示例。正如您所看到的,通過使用一個(gè)回調(diào)參數(shù),可以避免將 XHR 完全地簡單附加到腳本中。返回給回調(diào),并在可執(zhí)行 JavaScript 代碼中包裝數(shù)據(jù)對(duì)象。
JSONP 數(shù)據(jù)
var callback = function( data ) {
document.getElementById("main").innerHTML += "p>"+ data.sample.txt +"/p>";
}
var jsonpSample = function(e){
//create a script element
var jsonp = document.createElement("script");
//give it a source with the callback name appended in the query string
jsonp.src= "_assets/data/jsonp.do?callback=callback";
//add it to the doc
document.body.appendChild(jsonp);
e.preventDefault();
}
//wire up the event
document.getElementById("activate").addEventListener("click", jsonpSample, false);
庫示例
對(duì)于大多數(shù)開發(fā)人員來說,只有進(jìn)行學(xué)術(shù)研究的人才會(huì)對(duì) Ajax 請(qǐng)求的本質(zhì)感興趣。大多數(shù)實(shí)際工作是在一個(gè)或多個(gè) JavaScript 庫中完成。除了修補(bǔ)跨瀏覽器不兼容性,這些庫都提供了構(gòu)建于基礎(chǔ) API 之上的特性。下列示例展示了 3 個(gè)流行庫中的 GET 和 POST 示例來介紹不同的 API。
jQuery
讓我們從流行 jQuery 庫開始舉例說明。jQuery 的 Ajax 函數(shù)最近進(jìn)行了重寫,將幾個(gè)高級(jí)功能包含在內(nèi),這不是術(shù)語本文的討論范圍,但是所有 jQuery Ajax 請(qǐng)求的常見功能都以傳遞給該函數(shù)的配置對(duì)象的參數(shù)形式存在。另外還要注意的是,jQuery 有幾個(gè)便利的方法,比如 $.post 和$.get,這是常見請(qǐng)求配置的快捷鍵。
展示了使用 jQuery 獲取數(shù)據(jù)的簡要代碼。
一個(gè) jQuery GET 請(qǐng)求
/*
callback is a simple function that will be run
when the data is returned from the server
*/
var callback = function( data ) {
/*
it just adds a little bit of text to the document
data is the JSON object returned by the server.
*/
$("#main").append($("p />").text(data.sample.txt));
}
/*
Wire up the ajax call to this click event
*/
$("#activate").click(
function(){
//call $.ajax with a configuration object
$.ajax({
//it's just a get request
type: 'get',
//we're looking for this URL
url: '_assets/data/json-1.json',
//Our cool callback function
success: callback,
//it's going to be JSON
dataType: "json"
})
}
)
下面演示了如何發(fā)布和檢索簡單 JSON 對(duì)象。需要注意的是,這里使用了原生 JSON 對(duì)象來分析輸入數(shù)據(jù)。jQuery 文檔明確提及需要通過 JSON2.js 腳本增加不受支持的瀏覽器。
提供一個(gè)顯式錯(cuò)誤句柄使得成功請(qǐng)求和失敗請(qǐng)求都能得到優(yōu)雅的處理。jQuery 的錯(cuò)誤狀態(tài)帶有 3 個(gè)參數(shù),包括 XHR 對(duì)象本身,這支持健壯的錯(cuò)誤處理。
一個(gè) jQuery POST
/*
this is the object we're going to post
*/
var myMessages = {
positive : "Today is a good day",
negative : "Today stinks",
meh : "meh"
}
var callback = function( data ) {
$("#main").append($("p />").text(data.positive));
}
/*
Setting up a simple error handler.
It doesn't do much.
It's just nice to illustrate error handling.
*/
var errorHandler = function( xhr, textStatus, errorThrown ){
throw new Error("There was an error. The error status was " + textStatus );
}
/*
Here's where the action happens.
Attach an event to out simple button.
*/
$("#activate").click(
function(){
//call $.ajax with a configuration object
$.ajax({
//we're sending data to the server
type: 'POST',
//this is our URL
url: '_assets/data/post-responder.do',
/*
This is our data, JSON stringified
jQuery expects to use native JSON
or JSON2.js in unsupported browsers
*/
data: JSON.stringify(myMessages),
//Here's where we set up our callback function
success: callback,
//The data expected from the server
dataType: "json",
//And our simple error handler
error : errorHandler
}
)
}
);
Dojo
Dojo 不僅僅是下列示例中演示的簡單 Ajax 請(qǐng)求/DOM 操作。它實(shí)際上是為硬核應(yīng)用程序開發(fā)而構(gòu)建的。這就是說,以這種方式查看 API 仍然是值得期待的。
注意兩個(gè)獨(dú)立的 “Ajax” 函數(shù):xhrGet 和 xhrPost。另外還要注意的是,這里使用了 Dojo JSON 實(shí)用函數(shù)來分析輸入數(shù)據(jù)。下面 展示了一個(gè) GET 示例。
一個(gè) Dojo GET 請(qǐng)求
var callback = function( data ) {
//note the document.getelementById alias
dojo.byId("main").innerHTML += "p>"+ data.sample.txt +"/p>";
}
var getData = function(){
//xhrGet is for get requests
dojo.xhrGet({
//the URL of the request
url: "_assets/data/json-1.json",
//Handle the result as JSON data
handleAs: "json",
//The success handler
load: callback
});
}
// Use connect to attach events
dojo.connect( dojo.byId("activate"), "onclick", getData );
下面展示了一個(gè) Dojo POST,包含一個(gè)錯(cuò)誤句柄的配置。
Dojo POST
var myMessages = {
positive : "Today is a good day",
negative : "Today stinks",
meh : "meh"
}
var callback = function( data ) {
dojo.byId("main").innerHTML += "p>"+ data.positive +"/p>";
}
var errorHandler = function(){
throw new Error("We dun goofed.")
}
var postData = function(){
//not surprisingly xhrPost is for POST
dojo.xhrPost({
// The URL of the request
url: "_assets/data/post-responder.do",
//This will be JSON
handleAs: "json",
//Set the headers properly
headers: { "Content-Type": "application/json; charset=uft-8"},
//Use Dojo's JSON utility
postData: dojo.toJson(myMessages),
// The success handler
load: callback,
// The error handler
error: errorHandler
});
}
// Use connect to attach events
dojo.connect( dojo.byId("activate"), "onclick", postData );
Yahoo! 用戶界面 (YUI)
YUI 庫提供一個(gè)與前面兩個(gè)略有不同的模式。首先,YUI 返回整個(gè) XHR 對(duì)象,不僅解析數(shù)據(jù),還允許更準(zhǔn)確地操作返回?cái)?shù)據(jù)和整個(gè)請(qǐng)求的可見性。這也意味著開發(fā)人員需要了解 XHR 對(duì)象的來龍去脈。另外,這里還展示了 YUI 模塊加載程序 use() 的使用,需要注意的是,即使與 Ajax 沒有直接聯(lián)系(除了加載 io 模塊之外)。中有一個(gè) YUI 模塊列表,還有一個(gè)用作參數(shù)的回調(diào)函數(shù)。一旦運(yùn)行,就可以從 Yahoo! Content Delivery Network (CDN) 下載數(shù)據(jù)包,Yahoo! Content Delivery Network (CDN) 包含單個(gè)基于 CDN 的下載包中所需的所有模塊。
一個(gè) YUI GET 請(qǐng)求
// Create a new YUI instance and populate it with the required modules.
YUI().use('node','event', 'json', 'io', function (Y) {
var callback = function( id, xhr ) {
var data = Y.JSON.parse(xhr.responseText);
Y.one('#main').append("p>"
+ data.sample.txt
+"/p>");
}
Y.one("#activate").on('click',
function(){
Y.io( '_assets/data/json-1.json', {
//This is actually the default
method: 'get',
on: {success: callback}
})
}
)
});
下面中的 POST 示例中呈現(xiàn)的一個(gè)有趣的樣式風(fēng)格將所有響應(yīng)函數(shù)進(jìn)一步分割成 on 對(duì)象。
YUI POST
YUI().use('node','event', 'json', 'io', function (Y) {
var myMessages = {
positive : "Today is a good day",
negative : "Today stinks",
meh : "meh"
}
var callback = function( id, xhr ) {
var data = Y.JSON.parse(xhr.responseText);
Y.one('#main').append("p>"
+ data.positive
+"/p>");
}
var errorHandler = function( id, xhr){
throw new Error("There was an error. The error status was "
+ xhr.statusText
+".")
}
Y.one("#activate").on('click',
function(){
Y.io( '_assets/data/post-responder.do', {
method: 'post',
//Use the Y.JSON utility to convert messages to a string
data : Y.JSON.stringify(myMessages),
//All response methods are encapsulated in
//the on object
on: {success: callback,
failure: errorHandler }
})
}
)
});
正如您所看到的,基本模式在多數(shù)清單中都是一樣的。除了支持 ActiveX 控件和 JSONP 示例之外,它們基本上基于同一原理,只是在核心 JavaScript 交互的頂層具有不同的 API 變化。
請(qǐng)注意,除了這里列出的基本交互之外,所有這些庫還提供大量特性。盡管您可以做的大多數(shù) Ajax 工作可以通過簡單的 GET 和 POST 請(qǐng)求來處理,但讓自己熟悉所選擇的庫中的高級(jí)特性非常有用。
您可能感興趣的文章:- Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法總結(jié)
- jquery ajax提交表單數(shù)據(jù)的兩種方式
- jquery實(shí)現(xiàn)ajax提交form表單的方法總結(jié)
- jQuery使用ajaxSubmit()提交表單示例
- jquery ajax例子返回值詳解
- jquery中ajax使用error調(diào)試錯(cuò)誤的方法
- jquery中ajax處理跨域的三大方式
- 完美解決AJAX跨域問題
- Jquery中ajax方法data參數(shù)的用法小結(jié)