GoogleMaps探祕

1、Ajax 出現的背景
最近一段時間,關心 Web 開發的朋友在網絡上會經常聽到 Ajax 這個 buzzword。使用 Google 搜索,會搜索到無數自稱是 Ajax 的例子。這些例子的作者得意洋洋地展示自己學會了 xmlhttp 之後寫出的 hello world,自以爲已經精通了 Ajax。
那麼 Ajax 究竟是什麼?它是不是就是等同於 xmlhttp 呢?我們先來從源頭說起。
Ajax 這個詞的發明者是 Jesse James Garrett,他在這篇文章中發明了 AJAX 這個詞:
Ajax: A New Approach to Web Applications
點擊查看
這篇文章發表在 2005 年 2 月 18 號。可能今天的很多朋友還沒有讀過這篇文章,我來介紹一下其中的內容。
Ajax 是 Asynchronous JavaScript + XML 的縮寫,其中用到的主要的技術包括:
基於 XHTML/CSS 標準的展現
使用 DOM 的動態顯示和交互
使用 XML 和 XSLT 的數據交換和處理
使用 XMLHttpRequest 的異步數據獲取
JavaScript 把所有的一切捆綁在一起
Ajax 的交互模型和傳統基於 HTML Form 的交互模型有着非常大的區別。
作者通過以下這個圖對於傳統的交互模式和 Ajax 交互模式做了一個比較。
我們看到,在傳統的交互模式下,客戶端並無表示邏輯的執行,由服務器端執行所有的表示邏輯,然後把 HTML/CSS 傳給客戶端,客戶端僅僅做簡單的展現。
傳統的交互模式最大的問題就是任何哪怕是微小的交互行爲都需要到服務器端走一趟,這樣所帶來大量的延遲令用戶感覺很不舒服,也降低了用戶的工作效率。可能現在 Web 大量用戶已經習慣了等待一個頁面刷新的無聊時間,可是這不能成爲我們開發者推託有責任改善交互行爲的藉口。假設在用戶使用 B/S 應用之前還使用過 C/S 應用,在 C/S 應用中難道會有這樣可笑的事情發生嗎?
解決之道是什麼?我們再看一下 Ajax 的交互模式。
在客戶端多出來了一個 Ajax engine,而且服務器傳給客戶端的已經不再是 HTML/CSS,而是純的 XML 數據,客戶端通過 XMLHttp 向服務器端發送請求。所有的表示邏輯在客戶端通過 JS 腳本來執行,然後通過修改 DOM 來完成展現。
由於有了位於客戶端這個中間層,可以把原先必須在服務器端完成的很多交互工作放在了客戶端完成,而客戶端的 Ajax engine 的響應是即時的,因此用戶的交互體驗得到了極大的改善。我們可以通過下面這張圖來比較兩種交互模式下的時間分配。我們可以看出,傳統的基於 HTML Form 的交互模式下用戶的大量時間都浪費在了無聊的等待之上。這種新的交互模式的最大優點就是改善了用戶的體驗。此外還有很多其它方面的優點,例如不需要刷新頁面、減少了服務器的處理負擔、減少了交換的數據量等等。
那麼 Ajax 是不是一種神奇的新技術呢?完全不是,從 Ajax 所用到的上述核心技術來看,任何一種技術都是已經成熟了多年的技術,據我所知,最晚在 2001 年,所有這些技術都已經成熟並且進入了實用階段。因此,我僅僅是把 Ajax 看作是傳統的基於 XHTML/CSS/JS 開發的復興。實際上我以前所在的公司已經完全採用這種架構做 Web 開發有 3 年之久。我們已經完全摒棄了 HTML Form。所以當我看到這篇文章的時候想到,如果我們早發明一個詞,那這種新的 Web 開發模式可能就不叫 Ajax 了。不過這也證明了我們在幾年前做出的決定還是有先見之明的。
雖然在這個詞出現很多年以前就已經有大量的開發人員採用這種開發模式,不過現在既然出現了這個詞,起到了規範術語的作用。去年在 JavaEye 活動上做 XMLHttp 開發的講座時我感覺自己是相當另類的一個人,因爲那時候還沒有多少 J2EE 開發人員會對 JS 感興趣。現在 Ajax 越來越進入 J2EE Web 開發的主流領域,而且會長期保持它的生命力。
5 月底 JavaEye 的活動上聽熊節的演講,什麼也沒記住,只記住一個詞:古已有之。其實 Ajax 也是古已有之。Ajax 也不過就是新瓶裝舊酒,但是它把以前由美工單獨使用的這些技術(至今仍然有大量的 J2EE 開發人員認爲寫 JS 完全是美工的任務)完美地結合在了一起,產生出了巨大的價值。Ajax 是一種新的交互模式或者開發模式,而不是一個現成的框架。基於 Ajax 思想開發的應用都可以稱作是 Ajax 應用。Ajax 對於這些傳統的 J2EE 開發人員不怎麼關心的客戶端技術進行重新包裝,對於企業應用產生了巨大的價值。我們知道表示層開發始終是具有重大意義的,佔用了開發項目幾乎一半的工作量。而用戶很多時候就是看你的界面和交互,所以這部分是不能馬虎的。架構你可以稍微馬虎一點,基於 Spring/Hibernate 差也不會差很多。但是界面和交互是用戶立刻能感受到的東西,是不能馬虎的。
目前 Google 爲 Ajax 技術做出了巨大的投入,Google 這兩年推出的一些應用如 Gmail、Google Groups、Google Suggest、Google Maps 等等都採用了 Ajax 的技術。其中最爲醒目和最複雜的應用就是 Google Map。下面我將 Google Maps 作爲 Ajax 應用的一個典型爲大家做一些介紹。
 
2、Ajax 之實例應用——Google Maps
在做這個演講之前,我參考網上的一些資料對 Google Maps 做了一些 hack 的工作。目前已經可以做到除了地圖圖片要從 Google 請求外,其餘所有的數據都在本地運行。
但是因爲 Google Maps 前臺的代碼量比較大,並且是經過混淆的。所以整理這些代碼花費了比較多的功夫。目前這個工作尚未全部完成。因此以下講述的內容僅僅是根據我目前的成果。
Google Maps 使用了那些技術?
Google Maps 所使用的技術,基本上就是上面 Ajax 所提到的這些技術。
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 的主頁在
http://maps.google.com
Google Maps 每一張地圖的請求方式是:
http://maps.google.com/maps?ll=49.29,-123.12&spn=0.017998,0.027586&z=3&hl=en
我們看到每一張地圖有 4 個參數,按照值來算實際上是 6 個。
ll:地圖中心的精度和緯度
spn:地圖的範圍(跨度,分橫向和縱向)
z:地圖的縮放級別
hl:地圖採用的語言
Google Maps 每一張大的地圖實際上都是很多張小的 gif 貼圖。普通地圖每一張小圖片的大小爲 128x128 像素,衛星地圖每一張小圖片的大小爲 256x256 像素。每一張小圖片都有自己獨立的 URL,其格式爲:
http://mt.google.com/mt?v=.1&x=50&y=20&zoom=4
其中包括幾個參數:
v:當前版本號。.1 被推測爲 0.1 版
x:圖片的 x 索引
y:圖片的 y 索引
zoom:圖片的縮放級別。
每張地圖需要哪些貼圖使用固定的算法算出。然後自動像服務器請求這些貼圖。當地圖發生任何變化(例如:拖拽、移動、縮放等等)時,都會自動像服務器請求需要的圖片。例如剛纔我們看到了當地圖發生移動時,圖片會自動補全新的顯示區域。所有的這些計算和處理,全部都是使用 JS 在瀏覽器端完成的。

因爲瀏覽器有圖片的緩存功能,因此如果你經常查看某個相同地區的地圖的話,久而久之,瀏覽器會緩存大量的圖片,這樣你使用 Google Maps 的性能就會越來越好了。

Google Maps 還有搜索的功能,而且非常強大。我這裏錄製了一個簡單的演示。
Google Maps 還可以完成複雜的搜索,例如搜索 lax 這個地方的旅館,結果爲:
點擊地圖右邊旅館條目,可以在地圖上面出現旅館的說明。這個說明是使用 XSLT 技術產生的。
還可以搜索兩點之間的路徑。例如搜索 jfk to 350 5th ave, new york,得到的結果就是帶有兩點之間路徑路徑的地圖。這裏的路徑在 IE 上是使用 VML 畫的,而在其它瀏覽器上使用後臺自動生成的透明 png 圖片輿地圖圖片疊加產生。因爲 IE 完全是在客戶端完成,所以 IE 的性能會好一些。
另外 Google Maps 的地圖既可以加載在一個 DIV 中,也可以加載在一個 IFRame 中。熟悉 XMLHttp 的朋友知道,出現了 XMLHttp 後,需要通過隱藏的 IFrame 從服務器獲得數據的場合已經非常少了。但是 IFrame 還有一些其它的用途。IFrame 比 XMLHttp 有優勢的一個地方是 IFrame 可以和瀏覽器的歷史記錄結合起來,而 XMLHttp 做不到這一點。就是說如果數據來自於一個 IFrame,以後可以使用瀏覽器的back和forward功能這樣可以帶給用戶更好的交互體驗。比如剛纔我們看到的用戶搜索完 Boston,可能還想再看看 New York 的地圖,他可以簡單地使用瀏覽器的 back 按鈕,而不需要重新輸入 New York 再查一遍。他如果還想看 Boston 的地圖,那麼使用 forward 按鈕就可以了。
Google Maps 返回給前臺的數據爲 xml 格式,由前臺的 JS 腳本解析後作相應的處理。
這裏有這樣一個 xml 文件的例子。在這裏面實際上只有 center 和 span 是必須的。客戶端的腳本通過中心點位置和地圖跨度自動像服務器請求相應的圖片。
<?xml version="1.0"?>
<page>
<center lat="49.29" lng="-123.12"/>
<span lat="0.017998" lng="0.027586"/>
</page>
以上就是 Google Maps 主要的功能。我這裏主要從客戶端的角度來介紹,服務器端所提供的功能並未涉及。服務器端主要的作用是存儲數據。按照目前 15 個縮放級別,每個級別都要保留大量的貼圖文件,有人計算過,即使鄉村、荒地的很多地方不需要地圖,可以使用透明圖片代替,北美地區總共的數據量大約在幾十太的級別。Google 有世界上最強大的廉價 PC 服務器構成的 Linux 集羣。存儲這些數據並且提供良好的性能是完全沒有問題的。

其它的公司和個人是否可以使用 Google Maps 的技術?
其它的公司和個人完全可以使用 Google Maps 的服務。目前 Google 尚未對這一服務進行收費。因此你可以從 Google 的服務器上請求圖片,通過在你自己的服務器顯示給客戶。剛纔我做的演示完全是在本地運行的,所有的 xml 數據和 js 腳本全部都在本地,僅僅是貼圖來自於 Google 的服務器。Google 的 JS 腳本是有版權的,我這裏僅僅是出於研究的目的,把腳本下載到本地,做了一些修改以便於研究。對於商業應用,可能不能這樣做,可以在頁面中直接使用 Google 服務器上的腳本。因此使用 Google Maps 的方式就是在你自己的服務器上面生成定製的地圖數據,通過 XMLHttp 請求到客戶端,使用 Google Maps 的腳本解析,然後從 Google 請求貼圖數據。除了你自己的地圖數據外,還可以從其它服務器上獲得地圖數據,例如從 Google 的服務器上獲得數據。不過因爲 XMLHttp 只能從本域獲得數據,爲了獲得來自其它域的數據,需要在服務器端用 Servlet 實現一個代理,這個 Servlet 從其它域得到地圖數據後返回給客戶端。這樣一個 Servlet 寫起來是非常簡單的,只需要幾行代碼。同時在客戶端需要對 XMLHttp 對象做一個包裝,使得新的對象可以請求來自不同域的數據。
Google Maps 可以定製,Google 爲定製 Maps 服務提供了很多的便利。定製的方法就是提供自己定義的地圖數據文件,在剛纔這個文件中,overlay 中就是開發者定製的內容。其中定製了兩個點,當用戶點這兩個點的時候,會出現這兩個地點的說明文字。說明文字的產生使用了 XSLT 技術。例如我製作一個全部 New York 市的中餐館地圖,我可以把每個餐館的電話號碼、聯繫人姓名等等信息加在上面。Google Maps 把這些接口提供出來允許開發者與他們與他們合作,開發出來面向不同領域和羣體的地圖服務來。通過出讓一部分利潤來擴大其影響力,是精明的商業行爲。
Google Maps 的突出優點:
1、功能完善,具有常規地圖服務所有的功能。
2、性能優良。用戶幾乎從來不需要長期的等待。
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)
已經囊括了目前所有主流的瀏覽器。
Google Maps 通過自己開發的一套組件庫封裝了 IE 與其它瀏覽器的差別。主要的差別包括 XMLHttp、XMLDom 對象的創建語法,還有事件處理機制的不同。並且 Google Maps 儘量採用符合 Web 標準的技術,使得針對不同瀏覽器開發分支代碼的情況變得最小。
4、通過大量採用客戶端的技術,放棄了傳統的基於 HTML Form 的交互模式,因此使得用戶獲得了更好的交互體驗。
5、完全的組件化和麪向對象開發。
Google Maps 組件和麪向對象設計的水平是非常高的。所有主要的的控件全部封裝爲對象,使用面向對象的方式進行操作。

因爲 XMLHttp 只能得到本域的數據文件,爲了從其它地方獲得數據文件,可以在服務器端實現一個代理。簡單而言就是實現一個 Servlet,通過這個 Servlet 獲得其它域的數據文件,然後返回給客戶端。
爲此需要爲 XMLHttp 對象做一個包裝。我們來看看具體的包裝技術。
我對於 Google Maps 客戶端腳本的整理工作目前還沒有完全結束,因此今天具體的代碼講得比較少。主要是先從大的方面介紹了 Google Maps 的功能和採用的核心技術。下次有機會了我在給大家詳細剖析一下 Google Maps 前臺的代碼。當然這需要大家對於 XHTML/CSS/JavaScript/XSLT/XMLHttp 等技術都有相當的瞭解才行。
今天我首先給大家介紹了 Ajax 的由來和內涵。然後通過 Google Maps 作爲實例讓大家充分感受到了 Ajax 技術的優勢。目前 Ajax 已經有越來越流行,並且進入了主流 J2EE 開發的領域。不光是小公司對 Ajax 感興趣,大公司也越來越對 Ajax 產生了興趣。前天我的一位在 Oracle 做開發的朋友說他們公司現在對 Ajax 也非常感興趣,正在組織相關知識的學習。並且會考慮建造自己的 Ajax 組件庫和開發工具。他們公司以前使用 Applet 做過很多應用,但是 Applet 顯然已經是很落伍的技術,將來肯定會被 Java Web Start 所代替。而 JWS 也存在着一些問題。因此我認爲 Ajax 對於他們應該來說是一個更好的選擇。
雖然我做過很多 JavaScript 開發,非常喜歡這門語言。但是無庸諱言,JavaScript 目前還存在着一些問題,妨礙了大規模的組件化開發。主要的問題目前我認爲有以下兩個:
1、JavaScirpt 沒有 Java 那樣的 package 或者 C# 的 namespace 的概念,因此類和函數非常容易重名。這個問題不能僅僅通過制定命名規範來解決。
2、JavaScirpt 中的繼承不是真正的繼承,僅僅是所有的子類對象共享一個父類對象,這個父類對象相當於一個 Singleton,因此必須是無狀態的,不能保留自己的屬性。這個問題使得 JavaScript 難以支持多層繼承,無法構造大的繼承體系。
目前 ECMAScript4 正在開發,其中一個主要的目標就是爲 JavaScript 提供真正的面向對象編程能力。這個標準推出,到主要的瀏覽器支持這個標準還有相當長的時間。在目前階段解決這兩個問題有一些臨時的解決方案,由於時間原因我就不仔細講了。好在目前客戶端組件開發的規模比起服務器端還是要小得多,所以 JavaScript 目前的能力在大部分場合下都是夠用了。
由於目前各種主流瀏覽器都可以很好地支持 Web 標準。這裏我說的 Web 標準指的是 XHTML/CSS/ECMAScript/DOM/XSLT 這些技術。XMLHttp 將來的一天也會擠進標準的行列,目前對 XMLHttp 標準化的工作正在進行中。現在基於 Web 標準做開發已經成爲 Web 表示層開發的主流思想,徹底摒棄使用私有技術,只爲某種瀏覽器做開發的時機已經成熟。我並不是一個唯標準論者,我從來都是從注重實用的開發者的角度來考慮問題的。我也在以前也曾經只爲 IE 一種瀏覽器來做開發。但是今天,在我發現了基於標準開發並不會帶來額外的成本(已經幾乎不再需要寫針對不同瀏覽器的代碼分之),並且會帶來向後兼容的巨大價值的時候,我毫不猶豫地擁抱了 Web 標準。我也推薦大家以後儘量採用符合標準的方式來做開發,其中遇到的具體困難可以直接和我聯繫。我一定會貢獻出自己的經驗的。關於什麼是符合標準的開發方式,最佳實踐,在以後的活動中我們可以繼續來探討。
今天我要講的內容就是這些,對於 Google Maps 感興趣的朋友可以和我直接取得聯繫。我整理過的 Google Maps 的源代碼在適當的時候也會公佈出來。謝謝大家今天的參與!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章