最近一段時間,關(guān)心 Web 開發(fā)的朋友在網(wǎng)絡(luò)上會經(jīng)常聽到 Ajax 這個 buzzword。使用 Google 搜索,會搜索到無數(shù)自稱是 Ajax 的例子。這些例子的作者得意洋洋地展示自己學(xué)會了 xmlhttp 之后寫出的 hello world,自以為已經(jīng)精通了 Ajax。
那么 Ajax 究竟是什么?它是不是就是等同于 xmlhttp 呢?我們先來從源頭說起。
Ajax 這個詞的發(fā)明者是 Jesse James Garrett,他在這篇文章中發(fā)明了 AJAX 這個詞:
Ajax: A New Approach to Web Applications
點(diǎn)擊查看這篇文章發(fā)表在 2005 年 2 月 18 號??赡芙裉斓暮芏嗯笥堰€沒有讀過這篇文章,我來介紹一下其中的內(nèi)容。
Ajax 是 Asynchronous JavaScript + XML 的縮寫,其中用到的主要的技術(shù)包括:
基于 XHTML/CSS 標(biāo)準(zhǔn)的展現(xiàn)
使用 DOM 的動態(tài)顯示和交互
使用 XML 和 XSLT 的數(shù)據(jù)交換和處理
使用 XMLHttpRequest 的異步數(shù)據(jù)獲取
JavaScript 把所有的一切捆綁在一起
Ajax 的交互模型和傳統(tǒng)基于 HTML Form 的交互模型有著非常大的區(qū)別。
作者通過以下這個圖對于傳統(tǒng)的交互模式和 Ajax 交互模式做了一個比較。
我們看到,在傳統(tǒng)的交互模式下,客戶端并無表示邏輯的執(zhí)行,由服務(wù)器端執(zhí)行所有的表示邏輯,然后把 HTML/CSS 傳給客戶端,客戶端僅僅做簡單的展現(xiàn)。
傳統(tǒng)的交互模式最大的問題就是任何哪怕是微小的交互行為都需要到服務(wù)器端走一趟,這樣所帶來大量的延遲令用戶感覺很不舒服,也降低了用戶的工作效率??赡墁F(xiàn)在 Web 大量用戶已經(jīng)習(xí)慣了等待一個頁面刷新的無聊時間,可是這不能成為我們開發(fā)者推托有責(zé)任改善交互行為的借口。假設(shè)在用戶使用 B/S 應(yīng)用之前還使用過 C/S 應(yīng)用,在 C/S 應(yīng)用中難道會有這樣可笑的事情發(fā)生嗎?
解決之道是什么?我們再看一下 Ajax 的交互模式。
在客戶端多出來了一個 Ajax engine,而且服務(wù)器傳給客戶端的已經(jīng)不再是 HTML/CSS,而是純的 XML 數(shù)據(jù),客戶端通過 XMLHttp 向服務(wù)器端發(fā)送請求。所有的表示邏輯在客戶端通過 JS 腳本來執(zhí)行,然后通過修改 DOM 來完成展現(xiàn)。
由于有了位于客戶端這個中間層,可以把原先必須在服務(wù)器端完成的很多交互工作放在了客戶端完成,而客戶端的 Ajax engine 的響應(yīng)是即時的,因此用戶的交互體驗得到了極大的改善。我們可以通過下面這張圖來比較兩種交互模式下的時間分配。我們可以看出,傳統(tǒng)的基于 HTML Form 的交互模式下用戶的大量時間都浪費(fèi)在了無聊的等待之上。這種新的交互模式的最大優(yōu)點(diǎn)就是改善了用戶的體驗。此外還有很多其它方面的優(yōu)點(diǎn),例如不需要刷新頁面、減少了服務(wù)器的處理負(fù)擔(dān)、減少了交換的數(shù)據(jù)量等等。
那么 Ajax 是不是一種神奇的新技術(shù)呢?完全不是,從 Ajax 所用到的上述核心技術(shù)來看,任何一種技術(shù)都是已經(jīng)成熟了多年的技術(shù),據(jù)我所知,最晚在 2001 年,所有這些技術(shù)都已經(jīng)成熟并且進(jìn)入了實(shí)用階段。因此,我僅僅是把 Ajax 看作是傳統(tǒng)的基于 XHTML/CSS/JS 開發(fā)的復(fù)興。實(shí)際上我以前所在的公司已經(jīng)完全采用這種架構(gòu)做 Web 開發(fā)有 3 年之久。我們已經(jīng)完全摒棄了 HTML Form。所以當(dāng)我看到這篇文章的時候想到,如果我們早發(fā)明一個詞,那這種新的 Web 開發(fā)模式可能就不叫 Ajax 了。不過這也證明了我們在幾年前做出的決定還是有先見之明的。
雖然在這個詞出現(xiàn)很多年以前就已經(jīng)有大量的開發(fā)人員采用這種開發(fā)模式,不過現(xiàn)在既然出現(xiàn)了這個詞,起到了規(guī)范術(shù)語的作用。去年在 JavaEye 活動上做 XMLHttp 開發(fā)的講座時我感覺自己是相當(dāng)另類的一個人,因為那時候還沒有多少 J2EE 開發(fā)人員會對 JS 感興趣?,F(xiàn)在 Ajax 越來越進(jìn)入 J2EE Web 開發(fā)的主流領(lǐng)域,而且會長期保持它的生命力。
5 月底 JavaEye 的活動上聽熊節(jié)的演講,什么也沒記住,只記住一個詞:古已有之。其實(shí) Ajax 也是古已有之。Ajax 也不過就是新瓶裝舊酒,但是它把以前由美工單獨(dú)使用的這些技術(shù)(至今仍然有大量的 J2EE 開發(fā)人員認(rèn)為寫 JS 完全是美工的任務(wù))完美地結(jié)合在了一起,產(chǎn)生出了巨大的價值。Ajax 是一種新的交互模式或者開發(fā)模式,而不是一個現(xiàn)成的框架?;?Ajax 思想開發(fā)的應(yīng)用都可以稱作是 Ajax 應(yīng)用。Ajax 對于這些傳統(tǒng)的 J2EE 開發(fā)人員不怎么關(guān)心的客戶端技術(shù)進(jìn)行重新包裝,對于企業(yè)應(yīng)用產(chǎn)生了巨大的價值。我們知道表示層開發(fā)始終是具有重大意義的,占用了開發(fā)項目幾乎一半的工作量。而用戶很多時候就是看你的界面和交互,所以這部分是不能馬虎的。架構(gòu)你可以稍微馬虎一點(diǎn),基于 Spring/Hibernate 差也不會差很多。但是界面和交互是用戶立刻能感受到的東西,是不能馬虎的。
目前 Google 為 Ajax 技術(shù)做出了巨大的投入,Google 這兩年推出的一些應(yīng)用如 Gmail、Google Groups、Google Suggest、Google Maps 等等都采用了 Ajax 的技術(shù)。其中最為醒目和最復(fù)雜的應(yīng)用就是 Google Map。下面我將 Google Maps 作為 Ajax 應(yīng)用的一個典型為大家做一些介紹。
2、Ajax 之實(shí)例應(yīng)用——Google Maps
在做這個演講之前,我參考網(wǎng)上的一些資料對 Google Maps 做了一些 hack 的工作。目前已經(jīng)可以做到除了地圖圖片要從 Google 請求外,其余所有的數(shù)據(jù)都在本地運(yùn)行。
但是因為 Google Maps 前臺的代碼量比較大,并且是經(jīng)過混淆的。所以整理這些代碼花費(fèi)了比較多的功夫。目前這個工作尚未全部完成。因此以下講述的內(nèi)容僅僅是根據(jù)我目前的成果。
Google Maps 使用了那些技術(shù)?
Google Maps 所使用的技術(shù),基本上就是上面 Ajax 所提到的這些技術(shù)。
1. standards-based presentation using XHTML and CSS;
2. dynamic display and interaction using the Document Object Model;
3. data interchange and manipulation using XML and XSLT;
4. asynchronous data retrieval using XMLHttpRequest;
5. and JavaScript binding everything together.
Google Maps 每一張大的地圖實(shí)際上都是很多張小的 gif 貼圖。普通地圖每一張小圖片的大小為 128x128 像素,衛(wèi)星地圖每一張小圖片的大小為 256x256 像素。每一張小圖片都有自己獨(dú)立的 URL,其格式為:
http://mt.google.com/mt?v=.1&x=50&y=20&zoom=4其中包括幾個參數(shù):
v:當(dāng)前版本號。.1 被推測為 0.1 版
x:圖片的 x 索引
y:圖片的 y 索引
zoom:圖片的縮放級別。
每張地圖需要哪些貼圖使用固定的算法算出。然后自動像服務(wù)器請求這些貼圖。當(dāng)?shù)貓D發(fā)生任何變化(例如:拖拽、移動、縮放等等)時,都會自動像服務(wù)器請求需要的圖片。例如剛才我們看到了當(dāng)?shù)貓D發(fā)生移動時,圖片會自動補(bǔ)全新的顯示區(qū)域。所有的這些計算和處理,全部都是使用 JS 在瀏覽器端完成的。
因為瀏覽器有圖片的緩存功能,因此如果你經(jīng)常查看某個相同地區(qū)的地圖的話,久而久之,瀏覽器會緩存大量的圖片,這樣你使用 Google Maps 的性能就會越來越好了。
Google Maps 還有搜索的功能,而且非常強(qiáng)大。我這里錄制了一個簡單的演示。
Google Maps 還可以完成復(fù)雜的搜索,例如搜索 lax 這個地方的旅館,結(jié)果為:
點(diǎn)擊地圖右邊旅館條目,可以在地圖上面出現(xiàn)旅館的說明。這個說明是使用 XSLT 技術(shù)產(chǎn)生的。
還可以搜索兩點(diǎn)之間的路徑。例如搜索 jfk to 350 5th ave, new york,得到的結(jié)果就是帶有兩點(diǎn)之間路徑路徑的地圖。這里的路徑在 IE 上是使用 VML 畫的,而在其它瀏覽器上使用后臺自動生成的透明 png 圖片輿地圖圖片疊加產(chǎn)生。因為 IE 完全是在客戶端完成,所以 IE 的性能會好一些。
另外 Google Maps 的地圖既可以加載在一個 DIV 中,也可以加載在一個 IFRame 中。熟悉 XMLHttp 的朋友知道,出現(xiàn)了 XMLHttp 后,需要通過隱藏的 IFrame 從服務(wù)器獲得數(shù)據(jù)的場合已經(jīng)非常少了。但是 IFrame 還有一些其它的用途。IFrame 比 XMLHttp 有優(yōu)勢的一個地方是 IFrame 可以和瀏覽器的歷史記錄結(jié)合起來,而 XMLHttp 做不到這一點(diǎn)。就是說如果數(shù)據(jù)來自于一個 IFrame,以后可以使用瀏覽器的back和forward功能這樣可以帶給用戶更好的交互體驗。比如剛才我們看到的用戶搜索完 Boston,可能還想再看看 New York 的地圖,他可以簡單地使用瀏覽器的 back 按鈕,而不需要重新輸入 New York 再查一遍。他如果還想看 Boston 的地圖,那么使用 forward 按鈕就可以了。
Google Maps 返回給前臺的數(shù)據(jù)為 xml 格式,由前臺的 JS 腳本解析后作相應(yīng)的處理。
這里有這樣一個 xml 文件的例子。在這里面實(shí)際上只有 center 和 span 是必須的??蛻舳说哪_本通過中心點(diǎn)位置和地圖跨度自動像服務(wù)器請求相應(yīng)的圖片。
<?xml version="1.0"?>
<page>
<center lat="49.29" lng="-123.12"/>
<span lat="0.017998" lng="0.027586"/>
</page>
以上就是 Google Maps 主要的功能。我這里主要從客戶端的角度來介紹,服務(wù)器端所提供的功能并未涉及。服務(wù)器端主要的作用是存儲數(shù)據(jù)。按照目前 15 個縮放級別,每個級別都要保留大量的貼圖文件,有人計算過,即使鄉(xiāng)村、荒地的很多地方不需要地圖,可以使用透明圖片代替,北美地區(qū)總共的數(shù)據(jù)量大約在幾十太的級別。Google 有世界上最強(qiáng)大的廉價 PC 服務(wù)器構(gòu)成的 Linux 集群。存儲這些數(shù)據(jù)并且提供良好的性能是完全沒有問題的。
其它的公司和個人是否可以使用 Google Maps 的技術(shù)?
其它的公司和個人完全可以使用 Google Maps 的服務(wù)。目前 Google 尚未對這一服務(wù)進(jìn)行收費(fèi)。因此你可以從 Google 的服務(wù)器上請求圖片,通過在你自己的服務(wù)器顯示給客戶。剛才我做的演示完全是在本地運(yùn)行的,所有的 xml 數(shù)據(jù)和 js 腳本全部都在本地,僅僅是貼圖來自于 Google 的服務(wù)器。Google 的 JS 腳本是有版權(quán)的,我這里僅僅是出于研究的目的,把腳本下載到本地,做了一些修改以便于研究。對于商業(yè)應(yīng)用,可能不能這樣做,可以在頁面中直接使用 Google 服務(wù)器上的腳本。因此使用 Google Maps 的方式就是在你自己的服務(wù)器上面生成定制的地圖數(shù)據(jù),通過 XMLHttp 請求到客戶端,使用 Google Maps 的腳本解析,然后從 Google 請求貼圖數(shù)據(jù)。除了你自己的地圖數(shù)據(jù)外,還可以從其它服務(wù)器上獲得地圖數(shù)據(jù),例如從 Google 的服務(wù)器上獲得數(shù)據(jù)。不過因為 XMLHttp 只能從本域獲得數(shù)據(jù),為了獲得來自其它域的數(shù)據(jù),需要在服務(wù)器端用 Servlet 實(shí)現(xiàn)一個代理,這個 Servlet 從其它域得到地圖數(shù)據(jù)后返回給客戶端。這樣一個 Servlet 寫起來是非常簡單的,只需要幾行代碼。同時在客戶端需要對 XMLHttp 對象做一個包裝,使得新的對象可以請求來自不同域的數(shù)據(jù)。
Google Maps 可以定制,Google 為定制 Maps 服務(wù)提供了很多的便利。定制的方法就是提供自己定義的地圖數(shù)據(jù)文件,在剛才這個文件中,overlay 中就是開發(fā)者定制的內(nèi)容。其中定制了兩個點(diǎn),當(dāng)用戶點(diǎn)這兩個點(diǎn)的時候,會出現(xiàn)這兩個地點(diǎn)的說明文字。說明文字的產(chǎn)生使用了 XSLT 技術(shù)。例如我制作一個全部 New York 市的中餐館地圖,我可以把每個餐館的電話號碼、聯(lián)系人姓名等等信息加在上面。Google Maps 把這些接口提供出來允許開發(fā)者與他們與他們合作,開發(fā)出來面向不同領(lǐng)域和群體的地圖服務(wù)來。通過出讓一部分利潤來擴(kuò)大其影響力,是精明的商業(yè)行為。
Google Maps 的突出優(yōu)點(diǎn):
1、功能完善,具有常規(guī)地圖服務(wù)所有的功能。
2、性能優(yōu)良。用戶幾乎從來不需要長期的等待。
3、支持多種瀏覽器,目前 Google Maps 支持的瀏覽器包括以下這些:
IE 5.5+ (Windows)
Firefox 0.8+ (Windows, Mac, Linux)
Safari 1.2.4+ (Mac)
Netscape 7.1+ (Windows, Mac, Linux)
Mozilla 1.4+ (Windows, Mac, Linux)
Opera 7.5+ (Windows, Mac, Linux)
已經(jīng)囊括了目前所有主流的瀏覽器。
Google Maps 通過自己開發(fā)的一套組件庫封裝了 IE 與其它瀏覽器的差別。主要的差別包括 XMLHttp、XMLDom 對象的創(chuàng)建語法,還有事件處理機(jī)制的不同。并且 Google Maps 盡量采用符合 Web 標(biāo)準(zhǔn)的技術(shù),使得針對不同瀏覽器開發(fā)分支代碼的情況變得最小。
4、通過大量采用客戶端的技術(shù),放棄了傳統(tǒng)的基于 HTML Form 的交互模式,因此使得用戶獲得了更好的交互體驗。
5、完全的組件化和面向?qū)ο箝_發(fā)。
Google Maps 組件和面向?qū)ο笤O(shè)計的水平是非常高的。所有主要的的控件全部封裝為對象,使用面向?qū)ο蟮姆绞竭M(jìn)行操作。
因為 XMLHttp 只能得到本域的數(shù)據(jù)文件,為了從其它地方獲得數(shù)據(jù)文件,可以在服務(wù)器端實(shí)現(xiàn)一個代理。簡單而言就是實(shí)現(xiàn)一個 Servlet,通過這個 Servlet 獲得其它域的數(shù)據(jù)文件,然后返回給客戶端。
為此需要為 XMLHttp 對象做一個包裝。我們來看看具體的包裝技術(shù)。
我對于 Google Maps 客戶端腳本的整理工作目前還沒有完全結(jié)束,因此今天具體的代碼講得比較少。主要是先從大的方面介紹了 Google Maps 的功能和采用的核心技術(shù)。下次有機(jī)會了我在給大家詳細(xì)剖析一下 Google Maps 前臺的代碼。當(dāng)然這需要大家對于 XHTML/CSS/JavaScript/XSLT/XMLHttp 等技術(shù)都有相當(dāng)?shù)牧私獠判小?/div>
今天我首先給大家介紹了 Ajax 的由來和內(nèi)涵。然后通過 Google Maps 作為實(shí)例讓大家充分感受到了 Ajax 技術(shù)的優(yōu)勢。目前 Ajax 已經(jīng)有越來越流行,并且進(jìn)入了主流 J2EE 開發(fā)的領(lǐng)域。不光是小公司對 Ajax 感興趣,大公司也越來越對 Ajax 產(chǎn)生了興趣。前天我的一位在 Oracle 做開發(fā)的朋友說他們公司現(xiàn)在對 Ajax 也非常感興趣,正在組織相關(guān)知識的學(xué)習(xí)。并且會考慮建造自己的 Ajax 組件庫和開發(fā)工具。他們公司以前使用 Applet 做過很多應(yīng)用,但是 Applet 顯然已經(jīng)是很落伍的技術(shù),將來肯定會被 Java Web Start 所代替。而 JWS 也存在著一些問題。因此我認(rèn)為 Ajax 對于他們應(yīng)該來說是一個更好的選擇。
雖然我做過很多 JavaScript 開發(fā),非常喜歡這門語言。但是無庸諱言,JavaScript 目前還存在著一些問題,妨礙了大規(guī)模的組件化開發(fā)。主要的問題目前我認(rèn)為有以下兩個:
1、JavaScirpt 沒有 Java 那樣的 package 或者 C# 的 namespace 的概念,因此類和函數(shù)非常容易重名。這個問題不能僅僅通過制定命名規(guī)范來解決。
2、JavaScirpt 中的繼承不是真正的繼承,僅僅是所有的子類對象共享一個父類對象,這個父類對象相當(dāng)于一個 Singleton,因此必須是無狀態(tài)的,不能保留自己的屬性。這個問題使得 JavaScript 難以支持多層繼承,無法構(gòu)造大的繼承體系。
目前 ECMAScript4 正在開發(fā),其中一個主要的目標(biāo)就是為 JavaScript 提供真正的面向?qū)ο缶幊棠芰Α_@個標(biāo)準(zhǔn)推出,到主要的瀏覽器支持這個標(biāo)準(zhǔn)還有相當(dāng)長的時間。在目前階段解決這兩個問題有一些臨時的解決方案,由于時間原因我就不仔細(xì)講了。好在目前客戶端組件開發(fā)的規(guī)模比起服務(wù)器端還是要小得多,所以 JavaScript 目前的能力在大部分場合下都是夠用了。
由于目前各種主流瀏覽器都可以很好地支持 Web 標(biāo)準(zhǔn)。這里我說的 Web 標(biāo)準(zhǔn)指的是 XHTML/CSS/ECMAScript/DOM/XSLT 這些技術(shù)。XMLHttp 將來的一天也會擠進(jìn)標(biāo)準(zhǔn)的行列,目前對 XMLHttp 標(biāo)準(zhǔn)化的工作正在進(jìn)行中。現(xiàn)在基于 Web 標(biāo)準(zhǔn)做開發(fā)已經(jīng)成為 Web 表示層開發(fā)的主流思想,徹底摒棄使用私有技術(shù),只為某種瀏覽器做開發(fā)的時機(jī)已經(jīng)成熟。我并不是一個唯標(biāo)準(zhǔn)論者,我從來都是從注重實(shí)用的開發(fā)者的角度來考慮問題的。我也在以前也曾經(jīng)只為 IE 一種瀏覽器來做開發(fā)。但是今天,在我發(fā)現(xiàn)了基于標(biāo)準(zhǔn)開發(fā)并不會帶來額外的成本(已經(jīng)幾乎不再需要寫針對不同瀏覽器的代碼分之),并且會帶來向后兼容的巨大價值的時候,我毫不猶豫地?fù)肀Я?Web 標(biāo)準(zhǔn)。我也推薦大家以后盡量采用符合標(biāo)準(zhǔn)的方式來做開發(fā),其中遇到的具體困難可以直接和我聯(lián)系。我一定會貢獻(xiàn)出自己的經(jīng)驗的。關(guān)于什么是符合標(biāo)準(zhǔn)的開發(fā)方式,最佳實(shí)踐,在以后的活動中我們可以繼續(xù)來探討。
今天我要講的內(nèi)容就是這些,對于 Google Maps 感興趣的朋友可以和我直接取得聯(lián)系。我整理過的 Google Maps 的源代碼在適當(dāng)?shù)臅r候也會公布出來。謝謝大家今天的參與!
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點(diǎn)擊舉報。