Ajax简介
Ajax简介
我们知道,Internet经历了翻天覆地的重大变革。最早只有基于文本的简单浏览器,仅供科学家之间交流研究心得。如今,Internet已不可同日而语,它已经成为贸易和信息的中心。从最初诞生之日起,我们看到过许多新方法和新技术陆续登场,从开始的图形化浏览器到自由播(podcast,也称播客、随身播)等等。到了今天,Internet已经成为大量应用的首选平台(还记得你最后一次和旅行社直接打交道是什么时候吗?是不是早已经开始通过Internet完成这些事务了?)。不过,尽管Internet提供了很大的便利,但很少有人会把Web应用与桌面应用混淆不清。这一章将对Web应用的发展历程做一个简要的概述。回顾完过去之后,我们再来看看将来:Ajax。
Web应用的发展简史
刚开始时一切都那么简单。在美国,最初为了连接很少的几个顶尖研究机构,设计了最早的“Internet”,以便共同开展科学研究。不论是图书馆员、原子能物理学家,还是计算机科学家,都必须学习一个相当复杂的系统,1962年,麻省理工大学(MIT)的J.C.R. Licklider最早提出他的“Galactic Network”(超大网络)思想时,甚至还没有Firefox和Internet Explorer之类的概念。
Licklider后来继续在国防部高级研究计划局(Defense Advanced Research Projects Agency,DARPA)从事计算机研究,在那里他积极地宣扬网络化思想的重要性。与此同时,MIT的Leonard Kleinrock和Lawrence G. Roberts正在开展分组交换理论的研究,这是网络计算机的一个核心概念。在Thomas Merrill的帮助之下,Roberts于1965年进一步创建了第一个广域网,他通过一个拨号连接使麻萨诸塞州的一台TX-2连上了加利福尼亚州的一台Q-32。
1966年底,Roberts把他的实验结果提交给DARPA,在这里他设计了高级研究项目管理网络(Advanced Research Projects Administration Network,ARPANET)的计划。此时,Kleinrock正在加州大学的洛杉矶网络测量中心(Los Angeles Network Measurement Center),这里被选作ARPANET的第一个节点,正是在这里,1969年Bolt Beranek和Newman(BBN)成功地安装了第一个分组交换器,称为接口消息处理器(Interface Message Processors,IMP)。斯坦福研究中心选为第二个节点,1969年10月,实现了第一个主机到主机的消息交换。此后不久,又将加州大学的圣巴巴拉分部和犹他州大学增加为节点,这就是我们现在所称Internet的前身。
这个时期微机刚开始出现:数字设备公司(Digital Equipment Corporation)创建了PDP-1,其后PDP-8、PDP-11和VAX-11/780取得了巨大成功。计算机能力得到了极大提高,而且价格也越来越为人所接受,不像最初只有极少的几台大型机时那样贵得惊人。计算机已经走入平民大众;不过,可以看到,个人计算机还在进一步发展。
最初,研究人员认为传输控制协议(Transmission Control Protocol,TCP)只适用于大型系统,因为TCP就是为大型系统设计的。不过,麻省理工大学David Clark的研究小组发现,工作站之间可以大范围互联。Clark的研究,再加上20世纪80年代和90年代个人计算机领域的爆炸式发展,迅速推动了当今世界的前进。
20世纪80年代出现了几个大变化。随着主机数量从为数不多的几个发展到成千上万,需要为主机指定不同的名字,这样人们就不用费劲地去记它们的数字地址。这个变化,以及主机数量的飞速增长,催生了域名系统(Domain Name System ,DNS)的问世。另外,ARPANET从使用网络控制协议(Network Control Protocol,NCP)转换为使用传输控制协议/ Internet协议(Transmission Control Protocol/Internet Protocol,TCP/IP),这是军方使用的标准协议。到了20世纪80年代中期,Internet已经建成为一个连接不同研究人员的平台,而且其他网络也开始出现:美国国家航空和宇宙航行局(National Aeronautics and Space Administration)创建了SPAN。美国能源部(U.S. Department of Energy)建立了MFENet来研究磁力熔合能源,另外在国家科学基金(National Science Foundation)的资助下,还创建了CSNET来开展计算机科学研究。
1989年,欧洲粒子物理研究所(European Council for Nuclear Research,CERN)的Tim Berners-Lee提出了一个很有意思的概念。他认为,与其简单地引用其他人的工作,为什么不干脆链接呢?读一篇文章时,科学家可以打开所引用的文章。超文本(hypertext)当时相当流行,并利用了他先前在文档和文本处理方面的研究成果。Berners-Lee发明了标准通用标记语言(Standard Generalized Markup Language,SGML)的一个子集,称为超文本标记语言(HyperText Markup Language,HTML)。HTML的妙处在于,它能把应该如何展现文本与具体如何实现显示相分离。Berners-Lee不仅创建一个称为超文本传输协议(HyperText Transfer Protocol,HTTP)的简单协议,还发明了第一个Web浏览器,叫做WorldWideWeb。
浏览器历史
提到Web浏览器,大多数人都会想到无处不在的Microsoft Internet Explorer,直到最近像Firefox、Safari和Opera之类的浏览器日益兴起,这种情况才稍有改观。尽管许多新手可能认为Internet Explorer是市场上的第一个浏览器,但事实并非如此。实际上,第一个Web浏览器出自Berners-Lee之手,这是他为NeXT计算机创建的(这个Web浏览器原来取名叫WorldWideWeb,后来改名为Nexus),并在1990年发布给CERN的人员。Berners-Lee和Jean-Francois Groff将WorldWideWeb移植到C,并把这个浏览器改名为libwww。20世纪90年代初出现了许多浏览器,包括Nicola Pellow编写的一个行模式浏览器(这个浏览器允许任何系统的用户都能访问Internet,从Unix到Microsoft DOS都涵盖在内),还有Samba,这是第一个面向Macintosh的浏览器。
1993年2月,Illinois–Urbana-Champaign大学超计算应用国家中心的Marc Andreessen和Eric Bina为Unix发布了Mosaic。几个月之后,Aleks Totic为Macintosh发布了Mosaic的一个版本,这使得Mosaic成为第一个跨平台浏览器,它很快得到普及,并成为最流行的Web浏览器[1]。这个技术卖给了Spyglass,后来又归入Microsoft的门下,并用在Internet Explorer中。
1993年,塂萨斯大学的开发人员编写了一个基于文本的浏览器,叫做Lynx,它成为了字符终端的标准。1994年,挪威奥斯陆的一个小组开发了Opera,1996年这个浏览器得到了广泛使用。1994年12月,Netscape发布了Mozilla的1.0 版,第一个盈利性质的浏览器诞生。2002年又发布了一个开源的版本,这发展为后来流行的Firefox浏览器,于2004年11月发布。
Microsoft发布Windows 95时,把Internet Explorer 1.0作为Microsoft Plus!包的一部分同时发布。尽管这个浏览器与操作系统集成在一起,但大多数人还是坚持使用Netscape、Lynx或Opera。IE 2.0有了很大起色,增加了对cookie、安全套接字层(Secure Socket Layer,SSL)和其他新兴标准的支持。这个第二版还可以用于Macintosh,使之成为Microsoft的第一个跨平台浏览器。不过,大多数用户还是很执着,仍然使用他们用惯了的浏览器。
不过到了1996年夏天,Microsoft发布了3.0版本。几乎一夜之间,人们纷纷拥向Internet Explorer。当然,Netscape的浏览器还是要收费,Microsoft仍然免费提供Internet Explorer。关于浏览器领域谁主沉浮,Internet群体发生了两极分化,很多人担心Microsoft会像在桌面领域一样,在Web领域也一统天下。有些人则考虑到安全问题,而且不出所料,发布3.0版9天之后,就报告了第一个安全问题。到1999年发布Internet Explorer 5时,它已经成为使用最广的浏览器。
Web应用的发展历程
最初,所有Web页面都是静态的;用户请求一个资源,服务再返回这个资源。什么都不动,什么都不闪。坦率地讲,对于许多Web网站来说,这样也是可以的,这些网站的Web页面只是电子形式的文本,在一处生成,内容固定,再发布到多处。在浏览器发展的最初阶段,Web页面的这种静态性不成问题;科学家只是使用Internet来交换研究论文,大学院校也只是通过Internet在线发布课程信息。企业界还没有发现这个新“渠道”会提供什么商机。实际上,刚开始时,公司主页显示的信息通常很少,无非是一些联系信息,或者只是一些文档。不过,没过多久,Web用户就开始有新的要求,希望能得到更动态的网上体验。个人计算机成为企业的强劲后盾,从个人宿舍到住家办公室开始出现越来越多的计算机。随着Windows 95的问世,人们已经领教了Corel Word-Perfect和Microsoft Excel丰富的功能,所以用户的期望也越来越高。
CGI
要让Web更为动态,第一个办法是通用网关接口(Common Gateway Interface,CGI)。与静态的Web获取不同,可以使用CGI创建程序,用户发出请求时就会执行这个程序。假设你想在Web网站上显示销售的商品,可以利用一个CGI脚本来访问商品数据库,并显示结果。通过使用简单的HTML表单和CGI脚本,可以创建简单的前台应用,这样别人就可以通过浏览器来购买你的商品。可以用多种语言编写CGI脚本,从Perl到Visual Basic都可以,这使得掌握不同语言的人都能编写CGI脚本。
不过,要创建动态的Web页面,CGI并不是最安全的方法。如果采用CGI,任何人都可以在你的系统上执行程序。大多数情况下这可能没有问题,但是倘若一个用户有恶意企图,很可能利用这一点,让你的系统运行你本来不想运行的程序。尽管存在这个缺陷,但如今CGI仍在使用。
Applet
很显然,CGI可以有所改进。1995年5月,Sun的John Gage和Andreessen(目前在Netscape通信公司)宣布一种新的编程语言诞生,这就是Java。Netscape Navigator为这种新语言提供了支持,最初是为了支持机顶盒( 你可能认为,为了抢占在居室电子化方面的发展先机,最早涉足的公司是Microsoft和Sony)。就像所有革命一样,Java和Internet的出现恰到好处,在适当的时间、适当的地点横空出世,Java在Web上发布仅几个月,就已经有数以千计的人下载Java。由于Netscape的Navigator支持Java,动态Web页面掀开了新的一页:applet时代到来了。
Applet允许开发人员编写小应用,这些小应用可以嵌入在Web页面上。只要用户使用支持Java的浏览器,就可以在浏览器的Java虚拟机(Java Virtual Machine,JVM)中运行applet。尽管applet可以做很多事情,但它们也存在一些限制:通常不允许读写文件系统,不能加载本地库,而且可能无法启动客户端上的程序。除了这些限制外,applet还会在一个沙箱安全模型中运行,这有助于防止用户运行恶意代码。
对许多人来说,最初接触Java编程语言就是从applet开始的,当时这是创建动态Web应用的一种绝好的办法。Applet允许你在浏览器中创建一个“胖”客户应用,不过要在平台的安全限制范围内。当时,在很多领域都广泛使用了applet;但是,Web群体并没有完全被applet“征服”[2]。胖客户的开发人员都很熟悉一个问题:必须在客户端上部署适当的Java版本。因为applet在浏览器的虚拟机中运行,所以开发人员必须确保客户端安装了适当版本的Java。尽管这个问题并非无法解决,但确实妨碍了applet技术的进一步推广。而且如果applet写得不好,很可能对客户主机造成影响,这使许多客户对于是否采用基于applet的解决方案犹豫不定。如果你还不太熟悉applet,请看图1-1,图中显示了Sun的一个时钟applet。
图见P5-1
图1-1 Sun的一个时钟applet
JavaScript
与此同时,Netscape创建了一种脚本语言,并最终称之为JavaScript。(建立原型时本来叫做Mocha,正式发布之前曾经改名为LiveWire和LiveScript,不过最后终于确定为JavaScript)。设计JavaScript是为了让不太熟悉Java的网页设计人员和程序员能够更轻松地开发applet。(当然,Microsoft也推出了与JavaScript相对应的脚本语言,称为VBScript)。Netscape请Brendan Eich来设计和实现这种新语言,他认为需要的是一种动态类型脚本语言。由于缺乏开发工具,缺少有用的错误消息和调试工具,JavaScript很受非议,尽管如此,JavaScript仍然是一种创建动态Web应用的强大方法。
最初,创建JavaScript是为了帮助开发人员动态地修改页面上的标记,以便为客户提供更丰富的体验。人们越来越认识到,页面也可以当作对象,因此文档对象模型(Document Object Model,DOM)应运而生。刚开始,JavaScript和DOM紧密地交织在一起,但最后它们还是“分道扬镳”,并各自发展。DOM是页面的一个面向对象表示,可以用某种脚本语言(如JavaScript或VBScript)进行修改。
最后,万维网协会(World Wide Web Consortium,W3C)介入,并完成了DOM的标准化,而欧洲计算机制造商协会(European Computer Manufacturers Association,ECMA)批准JavaScript作为ECMAScript规范。根据这些标准编写的页面和脚本在遵循相应原则的任何浏览器上都应该有相同的外观和表现。
在最初的几年中,JavaScript的发展很是坎坷,这是许多因素造成的。首先,浏览器支持很不一致(即使是今天,同样的脚本在不同浏览器上也可能有不同的表现),而且客户可以自由地把JavaScript关闭(由于存在一些已知的安全漏洞,因此往往鼓励用户把JavaScript关掉)。由于开发JavaScript很有难度(你会用alert吗?),这使得许多开发人员退避三舍,很少使用这种语言,有些开发人员干脆不考虑 JavaScript,认为这是图形设计人员使用的一种“玩具”语言。许多人曾试图使用、测试和调试复杂的JavaScript,并为此身心俱疲,所以大多数人在经历了这种痛苦之后,最终还是满足于创建简单的基于表单的应用。
Servlet、ASP和PHP . . .哦,太多了!
尽管applet是基于Web的,但胖客户应用存在的许多问题在applet身上也有所体现。在大量使用拨号连接的年代(就算是今天,拨号连接也很普遍),要下载一个复杂applet的完整代码基,可能要花很多时间,这往往不是用户所能承受的。开发人员还要考虑客户端上的Java版本,有些虚拟机还有更多的要求[3]。理想情况下只需提供静态的Web页面,毕竟,这正是设计Internet的本来目的。当然,尽管静态页面是静态的,但是如果能在服务器上动态地生成内容,再把静态的内容返回,这就太好了。
在Java问世一年左右,Sun引入了servlet。你的Java代码不用像applet那样在客户浏览器中运行;它会在你控制的一个应用服务器上运行。这样,开发人员就能充分利用现有的业务应用,而且,如果需要升级为最新的Java版本,只需要考虑服务器就行了。Java推祟“一次编写,到处运行”,这一点使得开发人员可以选择最先进的应用服务器和服务器环境,这也是这种新技术的另一个优点。Servlet还可以取代CGI脚本。
Servlet是向前迈出的很大一步。Servlet提供了对整个Java应用编程接口(API)的完全访问,而且提供了一个完备的库可以处理HTTP。不过,Servlet不是十全十美的。使用Servlet来设计界面可能很困难。在一个典型的Servlet交互中,先要从用户得到一些信息,完成某种业务逻辑,然后使用一些“打印行”创建HTML,为用户显示结果。代码清单1-1所示的代码就相当常见。
代码清单1-1 简单的Servlet代码
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet SimpleServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World</h1>");
out.println("<p>Imagine if this were more complex.</p>");
out.println("</body>");
out.println("</html>");
out.close();
以上这一小段代码可以生成图1-2所示的一个相当简单的Web页面。
图见P6-1
图1-2 代码清单1-1中简单servlet的输出
servlet不仅容易出错,很难生成可视化显示,而且还无法做到人尽其才。一般地,编写服务器端代码的人往往是软件开发人员,他们只是对算法和编译器很精通,但不是能设计公司精美网站的图形设计人员。业务开发人员不仅要编写业务逻辑,还必须考虑怎么创建一致的设计。因此,很有必要将表示与业务逻辑分离。我们需要的就是JavaServer Pages(JSP)。
在某种程度上,JSP是对 Microsoft的 Active Server Pages (ASP)做出的一个回应。Microsoft从Sun在Servlet规范上所犯的错误汲取了教训,并创建了ASP来简化动态页面的开发。Microsoft增加了很棒的工具支持,并与其Web服务器紧密集成。JSP和ASP都设计为用于将业务处理与表示布局相分离,从这个意义上讲,二者是相似的。虽然存在一些技术上的差别(Sun也从Microsoft那里学到了教训),但它们有一个最大的共同点,都允许Web设计人员能够把重点放在布局上,而软件开发人员可以集中开发业务逻辑。代码清单1-2显示了一个简单的JSP。
代码清单1-2 简单的 JSP
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World</title>
</head>
<body>
<h1>Hello World</h1>
<p>This code is more familiar for Web developers.</p>
</body>
</html>
这个代码会生成图1-3所示的输出。
图见P8-1
图1-3 一个简单JSP的输出
当然,Microsoft和Sun并没有垄断服务器端解决方案。还有许多其他的方案,从PHP到ColdFusion等等在这个领域都有一席之地。有些开发人员喜欢新奇的工具;还有一些则倾向于更简单的语言。在目前来看,所有这些解决方案完成的任务都是一样的,它们都是要动态生成HTML。在服务器端生成内容可以解决发布问题;不过,与使用胖客户或applet所做的工作相比,用户从原始HTML得到的体验就太过单调和苍白了。下面几节将介绍几种力图提供更丰富用户体验的解决方案。
Flash
并不是只有Microsoft和Sun在努力寻找办法来解决动态Web页面问题。1996年夏天,FutureWave发布了一个名叫FutureSplash Animator的产品。这个产品起源于一个基于Java的动画播放器,FutureWave很快被Macromedia兼并,Macromedia则将这个产品改名为Flash。
利用Flash,设计人员可以创建令人惊叹的动态应用。公司可以在Web上发布高度交互性的应用,几乎与胖客户应用相差无几(见图1-4)。不同于applet、servlet和CGI脚本,Flash不需要编程技巧,很容易上手。在20世纪90年代末期,掌握Flash是一个很重要的特长,因为许多老板都非常需要有这种技能的员工。不过,这种易用性也是有代价的。
图见P9-1
图1-4 一个Flash应用
像许多解决方案一样,Flash需要客户端软件。尽管许多流行的操作系统和浏览器上都内置有所需的Shockwave播放器插件,但并非普遍都有。虽然能免费下载,但由于担心同时携带病毒,使得许多用户都拒绝安装这个软件。Flash应用可能还需要大量网络带宽才能正常地工作,另外,由于没有广泛的宽带连接,这也限制了Flash的推广(因此产生了“skip intro”链接)。尽管有些网站选择建立多个版本的Web应用,分别适应于不同的连接速度,但是许多公司都无法承受支持两个或更多网站所增加的开发开销。
总之,创建Flash应用需要专用的软件和浏览器插件。applet可以用文本编辑器编写,而且有一个免费的Java开发包(Java Development Kit,JDK),Flash则不同,使用完整的Flash工具包需要按点会费,每个点需要数百美元。尽管这些因素不是难以逾越的障碍,但它们确实减慢了Flash在动态Web应用道路上的前进脚步。
DHTML革命
Microsoft和Netscape发布其各自浏览器的第4版时,Web开发人员有了一个新的选择:动态HTML(dynamic HTML,DHTML)。有些人可能认为 DHTML不是一个W3C标准;它更像是一种销售手段。实际上,DHTML结合了HTML、层联样式表(Cascading Style Sheets,CSS)、JavaScript和DOM。这些技术的结合使得开发人员可以动态地修改Web页面的内容和结构。
最初对DHTML的反响很好。不过,它需要的浏览器版本还没有得到广泛采用。尽管Internet Explorer和Netscape都支持DHTML,但是它们的实现大相径庭,这说明开发人员必须知道他们的客户使用什么浏览器。而这通常意味着,需要大量代码来检查浏览器的类型和版本,这就进一步增加了开发的开销。有些人对于尝试这种方法很是迟疑,因为DHTML还没有一个官方的标准。不过,将来新标准有可能会出现。
XML衍生语言
20世纪90年代中期,基于SGML,衍生出了W3C的可扩展标记语言(eXtensible Markup Language,XML),自此以后,XML变得极为流行。许多人把XML视作为解决所有计算机开发问题的灵丹妙药,以至于XML几乎无处不在。实际上,Microsoft就已经宣布,Office 12将支持XML文件格式。
如今,我们至少有4种XML衍生语言可以创建Web应用(W3C的XHTML不包括在内):Mozilla的XUL ;XAMJ,这是结合Java的一种开源语言;Macromedia的MXML;以及Microsoft的XAML。
XUL: XUL(拼作“zool”)代表XML用户接口语言(XML User Interface Language),由Mozilla Foundation推出。流行的Firefox浏览器和Thunderbird邮件客户都是用XUL编写的。利用XUL,开发人员能构建功能很丰富的应用,可以与Internet连接,也可以没有连接。为了让熟悉DHTML的开发人员尽快地学会,XUL设计为可以为诸如窗口和按钮等标准界面部件提供跨平台支持。虽然它本身不是一个标准,但XUL所基于的都是标准,如HTML 4.0、CSS、 DOM, XML和 ECMAScript等等。XUL应用可以在浏览器上运行,也可以安装在一个客户主机上。
当然,XUL也不是没有缺点。XUL需要Gecko引擎,而且目前Internet Explorer还没有相应的插件。尽管Firefox在浏览器市场中已经有了一定的份额,但少了 Internet Explorer的支持还是影响很大,这使得大多数应用都无法使用XUL。目前开展的很多项目都是力图在多个平台上使用XUL,包括Eclipse。
XAML:XAML (拼作“zammel”)是Microsoft将推出的操作系统代码(名为Vista)的一个组件。XAML是可扩展应用标记语言(eXtensible Application Markup Language)的缩写,它为使用Vista创建用户界面定义了一个标准。与HTML类似,XAML使用标记来创建标准元素,如按钮和文本框等。XAML建立在Microsoft的 .NET平台之上,而且可以编译为.NET类。
应当很清楚XAML的局限所在。作为一个Microsoft产品,这就要求必须使用Microsoft的操作系统。在许多情况下(特别是公司中),这可能不成问题,但是有些公司使用的不是Microsoft的操作系统,总不能削足适履吧,就像是没有哪家砖瓦水泥公司会因为买家没有开某种车来就把他拒之门外。Vista交付的日期一再推迟,与此同时XAML也有了很大变化,不再只是一个播放器。据说,在未来几年内,我们可能会看到一个全新的XAML。
MXML:Macromedia创建了MXML,作为与其Flex技术一同使用的一种标记语言;MXML设计为与HTML很相似,可以以一种声明的方式来设计界面。与XUL和XAML类似,MXML提供了更丰富的界面组件,如DataGrid和TabNavigator,利用这些组件可以创建功能丰富的Internet应用。不过,MXML不能独立使用;它依赖于Flex和ActionScript编程语言来编写业务逻辑。
MXML与Flash有同样的一些限制。它是专用的,而且依赖于价格昂贵的开发和部署环境。尽管将来.NET可能会对MXML提供支持,但现在Flex只能在Java 2企业版(Java 2 Enterprise Edition,J2EE)应用服务器上运行,如Tomcat和IBM的WebSphere,这就进一步限制了MXML的广泛采用。
XAMJ: 让人欣喜的是,开源群体又向有关界面设计的XML衍生语言世界增加了新的成员。XAMJ作为另一种跨平台的语言,为Web应用开发人员又提供了一个工具。这种衍生语言基于Java,Java是当前最流行的面向对象语言之一,XAMJ也因此获得了面向对象语言的强大功能。XAMJ实际上想要替代基于XAML或HTML的应用,力图寻找一种更为安全的方法,既不依赖于某种特定的框架,也不需要高速的Internet连接。XAMJ是一种编译型语言,建立在“clientlet”体系结构之上,尽管基于XAMJ的程序也可以是独立的应用,但一般来讲都是基于Web的应用。在写这本书时,XAMJ还太新,所以还没有太多批评;不过,批评肯定会有的,让我们拭目以待。
谈到“以X开头的东西”时,别忘了W3C XForms规范。XForms设计为支持一种更丰富的用户界面,而且能够将数据与表示解耦合。无庸置疑,XForms数据是XML,这样你就能使用现有的XML技术,如XPath和XML Schema。标准HTML能做的,XForms都能做,而且XForms还有更多功能,包括动态检查域值,与Web服务集成等等。不同于其他的许多W3C规范,XForms不需要新的浏览器,你可以使用现在已有的许多浏览器实现。与大多数XML衍生语言一样,XForms是一种全新的方法,所以对于这种方法何时得到采纳,最好要耐心一些。
基本问题
有了以上了解,你怎么想?即使是要求最苛刻的客户应用,也已经把Web作为首选平台。很显然,基于Web的应用很容易部署,而对用户的这种低门槛正是Web应用最耀眼的地方。由于浏览器无处不在,而且无需下载和安装新的软件,用户利用基于浏览器的客户端就能很轻松地尝试新的应用。用户只需点击一个链接,就能运行你的应用,而不用先下载几MB的安装程序才能尝试。基于浏览器的应用也不考虑操作系统是什么,这说明不仅使用不同操作系统(如Linux和OS X)的人能运行你的应用,对你来说,也不必考虑针对不同的操作系统开发和维护多个安装包。
既然基于Web的应用是有史以来最好的东西,那我们为什么还要写这本书?如果回头看看Internet的起源,可以看到,最初Internet实际上就是让科学家们和学术机构交换文章和研究成果,这是一种简单的请求/响应模式。那时不需要会话状态,也不需要购物车;人们只是在交换文档。尽管你有很多办法来创建动态的Web应用,但如果想让应用在用户中真正深入人心,想要得到大量的用户,就必须在浏览器上大做文章,这说明,Internet以请求/响应模式做为基础,由此带来的同步性也造成了妨碍。
与Microsoft Word或Intuit Quicken之类的胖客户应用相比,Web模型当然只具有“平均性”,只能对所有用户做折衷考虑。不过,由于Web应用很容易部署,而且浏览器的发展相当迅速,这意味着大多数用户都已经学会了适应。但是,还是有许多人认为Web应用只是算“二等公民”,给人的用户体验不是太好。因为Internet是一个同步的请求/响应系统,所以浏览器中会整个页面进行刷新。最初,这种简单的请求并没有什么问题,如果用户做了一两处修改,就必须向服务器发回整个文档,而且要重新绘制整个页面。尽管这样是可以的,但是由于存在这种完全刷新限制,意味着应用确实很粗糙。
这并不是说开发人员只是袖手旁观,全然接受这种状况。Microsoft对于交互式应用有一定了解,而且对于这种标准请求/响应模式的限制一直都不满意,因此提出了远程脚本(remote scripting)的概念。远程脚本看似神奇,其实很简单:它允许开发人员创建页面,从而以一种异步的方式与服务器交互。例如,客户可以从一个下拉列表中选择状态,这样就会在服务器上运行一个脚本,并确定客户的发货花销。更重要的是,显示这些花销时无需刷新整个页面!当然,Microsoft的方案只适用于它自己的技术,而且需要Java,但有了这个进步,说明更丰富的浏览器应用并不是海市蜃楼。
对于同步页面刷新问题还有其他一些解决方案。针对Microsoft的远程脚本,Brent Ashley在创建JavaScript远程脚本(JavaScript Remote Scripting,JSRS)时开发了一个平台中立(独立于平台)的方案。JSRS依赖于一个客户端JavaScript库和DHTML,可以向服务器做异步的调用。与此同时,许多人利用了IFRAME标记,可以只加载页面中的某些部分,或者向服务器做“隐藏”的调用。尽管这是一个可行的方法,而且也为很多人所用,但它肯定不是最理想的,还有待改善。
Ajax
终于谈到这里了:客户希望得到一个功能更完备的应用,而开发人员想避开繁琐的部署工作,不想把可执行文件逐个地部署到数以千计的工作站上。我们已经做过很多尝试,但是任何一种方法都不像它原来标榜得那么完美。不过,最近又提出一个极其强大的工具。
如今我们又有了一个新的选择,新的工具,可以创建确实很丰富的基于浏览器的应用。我们有了Ajax。Ajax不只是一个特定的技术,更应算是一种技巧,不过其前身JavaScript主要是一种组件。我们知道,你可能会说“JavaScript根本不值一提”,但是由于Ajax的出现,人们对这种语言又有了新的兴趣,应用和测试框架再加上更优秀的工具支持,这些都减轻了开发人员肩头的重担。随着Atlas的引入,Microsoft对Ajax投入了大力支持,而名声不太好的Rails Web框架也预置了充分的Ajax支持。在Java世界中,Sun已经在其BluePrints Solutions Catalog中增加了许多Ajax组件。
坦率地讲,Ajax并不是什么新鲜玩艺。实际上,与这个词相关的“最新”术语就是XMLHttpRequest对象(XHR),即使是这个术语也早在Internet Explorer 5(于1999年春天发布)中就已经出现了,那时是作为 Active X控件露面的。不过,真正新的内容是浏览器的支持。原先,XHR对象只在Internet Explorer中得到支持(因此限制了它的使用),但是从Mozilla 1.0和Safari 1.2开始,对XHR对象的支持开始普及。这个很少使用的对象和相关的基本概念甚至已经出现在W3C标准中:DOM Level 3 加载和保存规范(DOM Level 3 Load and Save Specification)。现在,特别是随着Google Maps、Google Suggest、Gmail、Flickr、Netflix和A9等应用变得越来越炙手可热,XHR也已经成为事实上的标准。
与前面几页提到的方法不同,Ajax在大多数现代浏览器中都能工作,而且不需要任何专门的软件或硬件。实际上,这种方法的一大优势就是,开发人员不需要学习一种新的语言,也不必完全丢掉他们原先掌握的服务器端技术。Ajax是一种客户端方法,可以与J2EE、.NET、PHP、Ruby和CGI脚本交互,它并不关心服务器是什么。尽管存在一些很小的安全限制,但即使不清楚这些安全限制,你也可以现在就开始使用Ajax,而且能充分利用你原有的知识。
你可能会问“谁在使用Ajax?”。前面已经提到,Google显然就是最早采用Ajax的先驱之一,而且已经有很多这方面技术的例子,包括Google Maps、Google Suggest和Gmail,这还只是其中的几个应用而已。Yahoo!也开始引入Ajax控件,另外Amazon提供了一个简洁的搜索工具,其中大量使用了这个技术,例如,在钻石的某一方面上移动滑块,这会带来动态更新的结果(见图1-5)。并不是每次改变你的评价标准时都会更新页面,你在移动滑块时就会查询服务器,这样就能更快、更容易地明确你的选择。
Netflix,是一家很热门的DVD租借公司,它也使用了Ajax,用户浏览影片时,可以提供更详细的信息。如果客户把鼠标放在一个影片的图片上时,这个影片的ID就会发送到中心服务器,然后会出现一个“气泡”,提供这个影片的更多细节(见图1-6)。同样的,页面并不会刷新,每个影片的详细信息并不是放在隐藏的表单域中。利用这种方法,Netflix可以提供影片的更多信息,而不会把页面弄乱。客户浏览起来也更容易,他们不必点击影片,看完影片详细信息后再点击回到影片列表页面;客户只需把鼠标停在影片上,就这么简单!我们想要强调的是,Ajax并不限于“.com”之类的网站才能使用;公司的开发人员也开始涉足这个技术,有一些开发人员已经在使用Ajax来改善原来很丑陋的验证方案,或者用于动态地获取数据。
关键在于,Internet默认的请求/响应模式有了重大转变,这正是Ajax的核心所在,尽管这并非全新的内容。Web应用开发人员现在可以自由地与服务器异步交互,这说明,他们可以完成许多原本只能在胖客户上完成的任务。例如,用户输入一个邮政编码时,可以验证这个邮政编码是否正确,然后用相应的城市和州填写表单中的其他部分;或者,用户选择美国时,可以用美国的各个州来填写一个下拉列表。以前也可以用其他方式模拟这些工作,但是使用Ajax的话,这些工作会更加简单。
图见P14-1
图1-5 Amazon的钻石搜索页面
那么,是谁发明了Ajax?要找出真正的源头,为此总免不了一场争论;不过,有一点是确定的,2005年2月,Adaptive Path的JesseJames Garrett最早造了这个词。在他的文章“Ajax: A New Approach to Web Applications”(Ajax:Web应用的一种新方法)中,Garrett讨论了如何消除胖客户(或桌面)应用与瘦客户(或Web)应用之间的界限。当然,Google在Google Labs发布Google Maps和Google Suggest时,这个技术才真正为人所认识;而且此前已经有许多这方面的文章了。但确实是Garrett最早提出了这个词,否则我们就得罗罗嗦嗦地说上一大堆:异步(Asynchronous)、XMLHttpRequest、JavaScript、CSS、DOM等等。尽管原来把Ajax认为是Asynchronous JavaScript + XML(异步JavaScript + XML)的缩写,但如今,这个词的覆盖面有所扩展,允许浏览器与服务器通信而无需刷新当前页面的技术都涵盖在内。
图见P15-1
图1-6 Netflix的浏览器特性
你可能会说,“哦,那有什么大不了的?”。这么说吧,使用XHR,而且与服务器异步通信,这样就能创建更加动态的Web应用。例如,假设你有一个下拉列表,这个列表是根据另外一个域或下拉列表的输入来填写的。正常情况下,必须在加载第一个页面时把所有数据都发送给客户,然后使用JavaScript根据输入来填写下拉列表。这么做并不困难,但是会让你的页面变得很臃肿,取决于你的下拉列表到底有多“动态”,页面很可能膨胀得过大,这就有问题了。利用Ajax的话,当作为触发源的域有变化,或者失去了输入焦点,就可以向服务器做一个简单的请求,只要求得到更新下拉列表所需的部分信息。
来单独考虑一下验证。你写过多少JavaScript验证逻辑?用Java或C#编写验证逻辑可能很简单,但是由于JavaScript缺乏很好的调试工具,再加上JavaScript是一种弱类型语言,所以用JavaScript编写验证逻辑实在是一件让人头疼的事情,而且很容易出错。服务器上还很有可能重复这些客户端验证规则。使用XHR,可以对服务器做一个调用,触发某一组验证规则。这些规则可能比你用JavaScript编写的任何规则都更丰富、更复杂,而且你还能得到功能强大的调试工具和集成开发环境(IDE)。
你现在可能又会说,“这些事情我早已经用IFRAMES或隐藏框架做到了。”我们甚至还使用这种技术来提交或刷新过页面的一部分,而不是整个浏览器(页面);不能不承认,这确实可行。不过,许多人认为这种方法只是一种修补手段,以弥补XHR原来缺乏的跨浏览器支持。作为Ajax的核心,XHR对象设计为允许从服务器异步地获取任意的数据。
我们讨论过,传统的Web应用遵循一种请求/响应模式。如果没有Ajax,对于每个请求都会重新加载整个页面(或者如果利用IFRAMEs,则是部分页面)。原来查看的页面会放到浏览器的历史栈中(不过,如果使用了IFRAMEs,点击“后退”(back)按钮不一定能得到用户期望的历史页面)。与此不同,用XHR做出的请求不会记录在浏览器的历史中。如果你的用户习惯于使用后退按钮在Web应用中导航的话,就可能会产生问题。
可用性问题
前面谈到的都是用户的期望,除此以外,可用性也不能不提。Ajax方法相当新,还没有多少成熟的最佳实践或启发规则。不过,标准Web设计原则还是适用的。随着时间推移,越来越多的人开始尝试这种方法时,就会发现可能存在哪些限制,并建立适当的指导原则。也就是说,你应该让用户来指导你。取决于在应用中如何使用Ajax,你可能会动态地改变页面中的某些部分;习惯于整个浏览器完全刷新的用户可能不会注意到与以前有什么变化。这个问题引出了一些新的特性,如37signals所普及的黄褪技术(Yellow Fade Technique,YFT),这个特性已经用在Ajax的旗舰应用Basecamp中。
基本说来,YFT 是指,“取页面中有变化的部分,并置为黄色”。假设你的应用原本没有大量使用黄色,用户就很可能会注意到这种改变。过一段时间后,再让黄色逐渐褪色,直到恢复为原来的背景色。显然,你也可以选用你喜欢的其他颜色;所要做的就是把用户的注意力吸引到有变化的部分。
可能YTF并不适用于你的应用;你也可以选择用一种不那么明显但仍很有用的方式来提醒用户。Gmail在右上角显示了一个闪动的红色“Loading” 加载记号,提醒用户正在获取数据(见图1-7)。
图见P17-1
图1-7 Gmail的“Loading”记号
究竟要使用YFT还是一种类似的技术,这实际上取决于你的用户。最简单的方法是让一组用户代表来进行测试。可以通过文字问卷,也可以使用基于Web的原型应用,这要看你处在设计过程的哪个阶段,但是不论如何测试,在真正采用Ajax完成复杂设计之前都应该得到一些用户反馈。
而且要从小处做起。刚开始使用Ajax时,不应该马上就去创建一个可以调整列的动态门户网站。而是应该先试着处理客户端验证,逐步转向服务器端。等有所了解后,可以再尝试更动态的使用,如填写一个下拉列表,或者设置某些默认文本。
不管你要如何应用Ajax,要记住,别做稀奇古怪的事情。我们知道,这不算是一个学术性的建议。不过,目前这方面还没有严格的规则。听听你的用户怎么说,部署之前要先做测试,而且要记住,如果太过古怪,用户很快就会点击“skip intro”链接跳过你精心设计的这些部分。
你要知道使用Ajax 时有几个常犯的错误。我们已经讨论过,有变化时如何向用户提供可视化的提示,不仅如此,Ajax还会以其他方式改变标准的Web方法。首先,不同于IFRAMES和隐藏框架,通过XHR做出请求不会修改浏览器的历史栈。在许多情况下这没有什么问题(你可能会点击后退箭头,只是要看看是不是什么都没有改变,但这么做能有几次呢?),不过,如果你的用户确实想用后退按钮,就有问题了。
与其他基于浏览器的方法不同,Ajax不会修改地址栏中显示的链接,这说明你不能轻松地为一个页面建立书签,或者向朋友发送一个链接。对于许多应用来说,可能没有这个要求,但是如果你的网站提供了驾驶方向之类的东西,就要针对这个问题提供一个解决方案。
有一点很重要,不要过分使用Ajax。记住,JavaScript会在客户的浏览器上运行,如果有数千行JavaScript代码,可能会让用户感觉速度太慢。如果脚本编写不当,就会很快失去控制,特别是当通信量增加时。
Ajax允许你异步地完成操作,这个最大的优点同时也是它最突出的缺点。我们以前总是告诉用户,Web应用是以一种请求/响应模式完成操作的,用户也已经接受了这种思想,但是利用Ajax,就不再有这个限制。我们可以修改页面的一部分,如果用户不希望这样,他们很可能会被搞糊涂。所以,你要注意一定要让用户明白这一点,不要过分自作聪明。记住,只要有问题,就要请用户代表进行测试!
相关技术
你看到这本书时,可能已经了解了在应用中实现Ajax所需的大多数技术。重申一句,我们想强调的是,Ajax是一个客户端技术,不论你现在使用何种服务器端技术,都能使用Ajax,而不管使用的是Java、.NET、Ruby、PHP还是CGI。实际上,这本书里,我们并不考虑服务器端,而且假设你已经很清楚如何结合你日常工作中使用的服务器端技术。在后面的几百页中,我们强调的重点是客户端技术和方法,创建丰富的基于浏览器的应用时需要用到这些技术。
尽管可以使用你喜欢的任何服务器端技术,使用Ajax时,思想还是需要一点转变。在一个典型的Web应用中,服务器端代码会呈现一个完整的页面,并涉及一个完整的工作单元。利用Ajax,可能只返回一点点文本,而且只涉及一个业务应用的很小的子集。对于大多数有经验的Web开发人员来说,理解起来没有什么问题,但是一定要把这一点记住。
一些新兴的框架有助于使开发人员不用去考虑Ajax的一些细节;不过,你要对JavaScript有所了解。我们知道,JavaScript用起来可能很费劲。很遗憾,对此没有什么办法。 我们大多数人都学过这么一招,把“alert”作为一种系统输出来帮助调试,糟糕的是,这种技术使用得还很广。不过,现在我们有了新的利器。
除了JavaScript,你还要熟悉其他一些与表示相关的技术,如HTML、DOM和CSS。你不必是这方面的专家,但是基本了解还是必要的。这本书里我们会谈到需要你知道的大多数内容,这里没有谈到的内容可以参考网上的资源。
关于测试驱动(你肯定写了单元测试,对不对?),我们会介绍JsUnit和Selenium(见图1-8)。利用这些工具,可以先开发JavaScript测试,并检查浏览器兼容性测试。通常认为,下一代开发环境会对JavaScript提供更好的支持,另外一些与Ajax相关的技术会进一步减轻开发人员的负担。不断引入的脚本和框架也使开发变得更为简单。
图见P18-1
图1-8 Selenium
用法
既然你已经对Ajax产生了兴趣,还要知道重要的一点,什么时候应该使用Ajax技术,而什么时候不该用。首先,不要害怕在你的应用中尝试新的方法。我们相信,几乎每一个Web应用都能从Ajax技术得到好处;只不过不要矫枉过正,过于离谱就行了。从验证开始就很合适,但是不要限制你的主动性。你当然可以使用Ajax提交数据,但可能不能把Ajax作为提交数据的主要方法。
其次,惟一会影响你应用Ajax的就是浏览器问题。如果大量用户(或者特别重要的用户)还在使用比较老的浏览器,如Internet Explorer 5、Safari 1.2或Mozilla 1.0之前的版本,Ajax技术就不能奏效。如果这是一些很重要的用户,就要使用针对目标用户的跨浏览器的方法,而放弃Ajax,或者开发一个可以妥善降级的网站。浏览器支持可能不是一个重要因素,因为Netscape Navigator4在市场上的份额很小;不过,还是应该查看web日志,看看你的应用适用什么技术。
如前所述,验证和表单填写就非常适合采用Ajax实现。还可以使用DOM的“拖”技术建立真正动态的网站,如Google的个性化主页(见图1-9)。
图见P19-1
图1-9 Google的个性化主页
可以看到,Ajax为Web应用开发提供了新的机会。你不会再因为以往的专用技术或表现不佳而受到妨碍。利用Ajax,胖客户与瘦客户之间的界限不再分明,真正的蠃家则是你的用户。
设计考虑
既然对在哪里使用Ajax已经有所认识,下面再来谈谈应用Ajax的一些设计考虑。许多原则与Web应用的原则并无不同,不过还是有必要强调一下。要尽力减少客户和服务器之间的通信量。如果应用得当,Ajax会使你的应用响应更快,但是如果每次用户从一个域移到另一个域时你都会来回传递超量的数据,用户肯定不会满意。如果有问题,按标准约定行事。如果大多数应用都那么做,可能你也应该那么做。如果还有问题,可以看看Web桌面应用的有关标准。为此已经建立了一些模式,而且以后还会有更多的模式((www.ajaxpatterns.org)。
刚开始使用Ajax时,你的用户可能不清楚应用是怎么工作的。多年来我们一直在告诉用户:Web是以某种(同步)方式工作的,而Ajax则增加了异步组件,可能与之背道而驰。简单地说,不要让用户觉得奇怪。用户用跳格键离开最后一个域时,如果以前的应用(没有使用Ajax的应用)没有保存表单,那么使用Ajax之后的应用也不要保存表单。
实现Ajax时最重要的问题是要力求简单:完全从用户出发,要尽量“傻瓜”(类似于“傻瓜”相机,用户只需最简单的操作就能得到想要的照片)。要把用户放在心上,不要去做“简历驱动的设计”(译者注:有的开发人员希望完成一个复杂的设计,以便写在简历里,来证明自己的能力)。如果只是想让新老板接受你,并因此在应用中使用Ajax,这是不合适的;如果使用Ajax能让你的用户有更丰富的体验,那就义无反顾地使用Ajax吧。但是,别忘了,只是因为你会做,并不意味着应该做。要理智一些,先考虑你的用户,这样才对。
我们后面还会更多地谈到安全,但是这里需要先说明一点,Ajax有一些安全考虑。记住,可以在浏览器中查看源代码,这说明任何人都能知道你是怎么创建你的小部件的。建立XHR对象时必须包含统一资源定位符(uniform resource locators,URL),所以可能会有恶意用户修改你的网站,运行他们自己的代码。谨慎地使用Ajax可以降低这种风险。
小结
Internet最初只是要连接研究人员,让他们共享信息,时至今日,Internet已经得到了巨大的发展。Internet开始时只有简单的文本浏览器和静态页面,但是如今几乎每家公司都有一个亮丽的网站,想找到一个粗糙的网站倒是很不容易。最早谁能想得到,有一天人们能在网上共同研究新型汽车,或者购买最新的Stephen King小说呢?
胖客户应用的开发人员都饱受部署之苦,因为要把应用部署到数以千计的用户机器上,他们急切地希望Web能够减轻他们的负担。多年以来,已经出现了许多Web应用技术,有些是专用的,另外一些需要高超的编程能力。在用户体验方面,尽管这些技术有弱有强,但没有哪个技术能使瘦客户应用达到桌面应用的水平。不过,由于很容易部署,有更大的客户群体,而且维护开销更低,这说明尽管浏览器存在一定的局限性,仍是许多应用的首选目标平台。
开发人员可以使用一些技巧来绕过Internet对开发人员的麻烦限制。利用各种远程脚本方法和HTML元素,开发人员可以与服务器异步地通信,但是直到主流浏览器对XMLHttpRequest对象提供了支持,真正的跨浏览器方法才有可能。Google、Yahoo和Amazon等公司已经走在前面,我们终于看到基于浏览器的应用也能与胖客户应用不相上下。利用Ajax,你可以尽享这两方面的好处:代码位于你能控制的服务器上,而且只要客户有浏览器,就能访问一个能提供丰富用户体验的应用。