1、Ajax 出现的背景
最近一段时间,关心 Web 开发的朋友在网络上会经常听到 Ajax 这个 buzzword。使用 Google 搜索,会搜索到无数自称是 Ajax 的例子。这些例子的作者得意洋洋地展示自己学会了 xmlhttp 之后写出的 hello world,自以为已经精通了 Ajax。
最近一段时间,关心 Web 开发的朋友在网络上会经常听到 Ajax 这个 buzzword。使用 Google 搜索,会搜索到无数自称是 Ajax 的例子。这些例子的作者得意洋洋地展示自己学会了 xmlhttp 之后写出的 hello world,自以为已经精通了 Ajax。
那么 Ajax 究竟是什么?它是不是就是等同于 xmlhttp 呢?我们先来从源头说起。
Ajax 这个词的发明者是 Jesse James Garrett,他在这篇文章中发明了 AJAX 这个词:
Ajax: A New Approach to Web Applications
点击查看
Ajax: A New Approach to Web Applications
点击查看
这篇文章发表在 2005 年 2 月 18 号。可能今天的很多朋友还没有读过这篇文章,我来介绍一下其中的内容。
Ajax 是 Asynchronous JavaScript + XML 的缩写,其中用到的主要的技术包括:
基于 XHTML/CSS 标准的展现
使用 DOM 的动态显示和交互
使用 XML 和 XSLT 的数据交换和处理
使用 XMLHttpRequest 的异步数据获取
JavaScript 把所有的一切捆绑在一起
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 交互模式做了一个比较。
我们看到,在传统的交互模式下,客户端并无表示逻辑的执行,由服务器端执行所有的表示逻辑,然后把 HTML/CSS 传给客户端,客户端仅仅做简单的展现。
传统的交互模式最大的问题就是任何哪怕是微小的交互行为都需要到服务器端走一趟,这样所带来大量的延迟令用户感觉很不舒服,也降低了用户的工作效率。可能现在 Web 大量用户已经习惯了等待一个页面刷新的无聊时间,可是这不能成为我们开发者推托有责任改善交互行为的借口。假设在用户使用 B/S 应用之前还使用过 C/S 应用,在 C/S 应用中难道会有这样可笑的事情发生吗?
解决之道是什么?我们再看一下 Ajax 的交互模式。
在客户端多出来了一个 Ajax engine,而且服务器传给客户端的已经不再是 HTML/CSS,而是纯的 XML 数据,客户端通过 XMLHttp 向服务器端发送请求。所有的表示逻辑在客户端通过 JS 脚本来执行,然后通过修改 DOM 来完成展现。
在客户端多出来了一个 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 开发的主流领域,而且会长期保持它的生命力。
虽然在这个词出现很多年以前就已经有大量的开发人员采用这种开发模式,不过现在既然出现了这个词,起到了规范术语的作用。去年在 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 做了一些 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.
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:地图采用的语言
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:图片的缩放级别。
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>
这里有这样一个 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 组件和面向对象设计的水平是非常高的。所有主要的的控件全部封装为对象,使用面向对象的方式进行操作。
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 难以支持多层继承,无法构造大的继承体系。
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 的源代码在适当的时候也会公布出来。谢谢大家今天的参与!