1.2 用JavaScript来写浏览器上的应用
1.2.1 我要做一个聊天室
大概是在1998年12月中旬,我的个人网站完工了。
这是一个文学网站,这个网站在浏览器上用到了Java Applet和JavaScript,并且为IE 4.0浏览器提供了一个称为“搜索助手”的浮动条(FloatBar),用于快速向服务器提交查询文章的请求。而服务器端则使用了Delphi开发的ISAPI CGI,运行于当时流行的Windows NT上的IIS系统。
我接下来的想法是:我要做一个聊天室。因为在我的个人网站中,论坛、BBS等都有网站免费提供,唯独没有聊天室。于是在1999年春节期间,我在四川的家中开始做这个聊天室并完成了原型系统(我称之为beta 0);一个月后,这个聊天室的beta 1版终于在互联网上架站运行(见图1-1)。
图1-1 聊天室的beta 1版的界面
这个聊天室的功能集设定见表1-1。
表1-1 聊天室beta 1版的功能集设定
在这个聊天室的右上角有一个“隐藏帧”,是用FRAMESET来实现的。这是最早期实现Web RPC(Remote Procedure Call)的方法,那时网页开发还不推荐使用IFRAME,也没有后来风行的AJAX。因此从浏览器下方的状态栏中,也可以看到这个聊天室在调用服务器上的dll文件—这就是那个用Delphi写的ISAPI CGI。当时我还不知道PHP,而ASP也并不那么流行。
这个聊天室在浏览器上大量地使用了JavaScript。一方面,它用于显示聊天信息、控制CSS显示和实现界面上的用户交互;另一方面,我用它实现了一个Command Center,将浏览器中的行为编码成命令发给服务器的ISAPI CGI。这些命令被服务器转发给聊天室中的其他用户,目标用户浏览器中的JavaScript代码能够解释这些命令并执行类似“更名”“更新列表”之类的功能—服务器上的ISAPI基本上只用于中转命令,因此效率非常高。
你可能已经注意到,这其实与后来兴起的AJAX、前后端分离架构,包括最近两年出现的所谓“JAMStack”如出一辙。
虽然这个聊天室在beta 0版时还尝试支持了NN 4,但在beta 1时我就放弃了—因为IE 4提供的DHTML模型已经可以使用insertAdjacentHTML动态更新网页了,而NN 4仍只能调用document.write来修改页面。
1.2.2 Flash的一席之地
我所在的公司也发现了互联网上的机会,成立了互联网事业部。我则趁机提出了一个庞大的计划,名为JSVPS(JavaScript Visual Programming System)。
JSVPS在服务器端表现为dataCenter与dataBaseCenter。前者用于类似聊天室的即时数据交互,后者则用于类似论坛中的非即时数据交互。在浏览器端,JSVPS提出了开发网页编辑器和JavaScript组件库的设想。
这时微软的IE 4.x已经从浏览器市场拿到了超过70%的市场份额,开始试图把Java Applet从它的浏览器中赶走。这一策略所凭借的,便是微软在IE中加入的ActiveX技术。于是Macromedia Flash就作为一个ActiveX插件“挤”了进来。Flash在矢量图形表达能力和开发环境方面表现优异,使当时的Java Applet优势全失。一方面微软急于从桌面环境中挤走Java,以应对接下来.NET与Java的语言大战;另一方面Flash与Dreamweaver当时只是网页制作工具,因此微软并没有放在眼里,就假手Flash赶走了Java Applet。
Dreamweaver系列的崛起,使得网页制作工具的市场变得几乎没有了悬念。重心放在Java Applet的工具,例如,HotDog等都纷纷落马;而纯代码编辑的工具,如国产的CutePage则被Dreamweaver慢慢地蚕食着市场。同样的原因,JSVPS项目在浏览器端“开发网页编辑器”的设想最终未能实施,而“JavaScript组件库”也因为市场不明朗一直不能投入开发。
而在服务器端的dataCenter与dataBaseCenter都成功地投入了商用。此后,我在聊天室上花了更多的精力。到2001年下半年,我的聊天室已经开始使用页签形式来管理多房间同时聊天,并加入语言过滤、表情、行为和用户界面定制等功能。而且,通过对核心代码的分离,聊天室已经衍生出“Web即时通信工具”和“网络会议室”这样的版本。
2002年年初,聊天室发布的最终版本(v2.8)的功能设定已经远远超出了现在网上所见的Web聊天室的功能集。在图1-2所示的示例中,聊天室包括颜色选取器、本地历史记录、多房间管理、分屏过滤器、音乐、动作、表情库和Outlook样式的工具栏,以及中间层叠的窗体,都是由DHTML与CSS来动态实现的。在后台驱动这一切的,就是JavaScript。
图1-2 聊天室最终版本的界面
我没有选择这时已经开始流行的Flash,因为用DHTML做聊天室的界面效果并不逊于Flash,也因为在RWC与RIA的战争中,我选择了前者。
1.2.3 RWC与RIA之争
追溯RWC的历史,就需要从“动态网页(DHTML,Dynamic HTML)”说起。
在1997年10月发布的IE 4中,微软提供了JScript 3,这包括当时刚刚发布的ECMAScript Edition 1,以及尚未发布的JavaScript 1.3的很多特性。最重要的是,微软颇有创见地将CSS、HTML与JavaScript技术集成起来,提出了DHTML开发模型(Dynamic HTML Model),这使得几乎所有的网页都开始倾向于“动态(Dynamic)”。
开始,人们还很小心地使用着脚本语言,但当微软用IE 4在浏览器市场击败网景之后,很多人发现,没有必要为10%的人去多写90%的代码。因此,“兼容”和“标准”变得不再重要。于是DHTML成了网页开发的事实标准,以致后来由W3C提出的DOM(Document Object Model)在很长一段时间都没有产生任何影响。
这时,成熟的网页制作模式,使得一部分人热衷于创建更有表现能力和实用价值的网页,他们把这样的浏览器和页面叫作“Rich Web Client”,简称RWC。Rich Web的概念产于何时已经不可考,但Erik Arvidsson一定是实践其的先行者,他也可能是最早通过JavaScript+DHTML实现menu、tree及tooltip的人。1998年年末,他已经在个人网站上实现了一个著名的WebFX Dynamic WebBoard(见图1-3)。这套界面完整地模仿了Outlook,因而是在Rich Web Client上实现类Windows界面的经典之作。
图1-3 WebFX Dynamic WebBoard的仿Outlook界面
而在这时盛行的Flash也需要一种脚本语言来表现动态的矢量图形。因此,Macromedia很自然地在Flash 2中加入了一种名为Action的脚本支持。在Flash 3时,该脚本参考了JavaScript的实现,变得更为强大。随后,Macromedia又干脆以JavaScript作为底本完成了自己的ActionScript,并加入Flash 5中。随着ActionScript被浏览器端开发人员逐渐接受,这种语言也日渐成熟,于是Macromedia开始提出自己的对“浏览器端开发”的理解。这就是有名的RIA(Rich Internet Application)。
这样一来,RIA与RWC分争“富浏览器客户端应用(Rich Web-client Application,RWA)”的市场局面出现了—微软开始尝到自己种下的苦果:一方面它通过基于ActiveX技术的Flash赶走了Java Applet,另一方面却又使得Dreamweaver和Flash日渐做大。实在是前门拒虎,后门进狼。微软用丢失网页编辑器和网页矢量图形事实标准的代价,换取了在开发工具(例如,Visual Studio.NET)和语言标准(例如,CLS,Common Language Specification)方面的成功。而这个代价的直接表现之一,就是RIA对RWC的挑战。
RIA的优势非常明显,在Dreamweaver UltraDev 4.0发布之后,Macromedia成为网页编辑、开发类工具市场的领先者。而在服务器端,有基于Server Page思路的ColdFusion、优秀的J2EE应用服务器JRun和面向RIA模式的Flash组件环境Flex。这些构成了完整的B/S三层开发环境。然而似乎没有人能容忍Macromedia独享浏览器开发市场,并试图染指服务器端的局面,所以RIA没有得到足够的商业支持。另一方面,ActionScript也离JavaScript越来越远,既不受传统网页开发者的青睐,对以设计人员为主体的Flash开发者来讲又设定了过高的门槛。
但RWC的状况则更加尴尬。因为JavaScript中尽管有非常丰富的、开放的网络资源,但却找不到一套兼容的、标准的开发库,也找不到一套规范的对象模型(DOM与DHTML纷争不断),甚至连一个统一的代码环境都不存在(没有严格规范的HOST环境)。
在RIA热捧浏览器上的Rich Application市场的同时,自由的开发者们则在近乎疯狂地挖掘CSS、HTML和DOM中的宝藏,试图从中寻找到RWC的出路。支持这一切的,是JavaScript 1.3~1.5,以及在W3C规范下逐渐成熟的Web开发基础标准。而在这整个过程中,RWC都只是一种没有实现的、与RIA的商业运作进行着持续抗争的理想而已。