2.1 Web应用程序的工作流程

1973年,美国开始将阿帕网(Advanced Research Projects Agency Network,ARPANET)扩展成互联网。当时的互联网和现在所看到的互联网完全不同,不仅非常原始,传输速度也慢得惊人,但是却已具备互联网的基本形态和功能。此后互联网在规模和速度两个方面都得到了飞速的发展。

今天看似平常的网上购物、支付、浏览信息等操作都是基于互联网实现的。但是如果当年没有蒂姆·伯纳斯·李提出万维网这个创意,今天的人们可能正在通过其他方式来使用互联网,那些人们耳熟能详的Web应用程序也可能是另一个样子。

互联网最初的目的是实现信息的共享,通过互联网连接在一起的计算机彼此间可以分享自己存储的文件。人们可以像浏览自己的计算机一样去查看其他人的计算机,但是当计算机中存储的内容越来越多时,这显然变成了一件令人十分苦恼的工作。设想一下,这个难度不亚于在春运期间的火车站里寻找一个走散的同伴。

蒂姆·伯纳斯·李显然不屑于做这种重复的工作,于是他将计算机中重要文档的地址都进行了记录,并以超文本的形式保存为一个文件。这样人们只需要浏览这个文件,就能知道自己的计算机中都有哪些文件,以及这些文件都处于什么位置。但是这个文件还不能通过互联网访问。

到了1990年,蒂姆·伯纳斯·李将欧洲核子研究组织(European Organization for Nuclear Research)的电话号码簿制作成了第一个Web应用程序,并在自己的计算机上运行了它。网络用户可以通过访问蒂姆·伯纳斯·李的计算机来查询每名研究人员的电话号码。这个在今天看起来平淡无奇的想法,却是改变人类命运的伟大发明。蒂姆·伯纳斯·李为他的这个发明起名为World Wide Web(也就是WWW)。而他的计算机也成为世界上的第一台Web服务器。至此,万维网开始走上了历史舞台。

1991年,蒂姆·伯纳斯·李又发明了万维网的3项关键技术:

超文本标记语言(Hyper Text Markup Language,HTML);

统一资源标识符(Uniform Resource Identifier,URI);

超文本传输协议(Hyper Text Transfer Protocot,HTTP)。

这些规范时至今日仍然发挥着重要的作用。当然,仅仅凭借这3项技术并不能实现现在的Web应用程序,不过在万维网刚刚诞生时,它们已经足够用了。

当前的Web应用程序分为静态和动态两种类型,而在最初的万维网时期,则只有静态Web应用程序。当时的Web应用程序的工作原理很简单,程序员只需按照HTML编写静态页面并将其放置在Web服务器中。HTML十分简单易学,它并不是一种编程语言,而是一种标记语言,依靠标记标签来描述网页。

如图2-1所示,当用户需要访问这台Web服务器中的index.html文件时,需要在自己的浏览器输入目标URI。URI是标识某一互联网资源名称的字符串,Web服务器上可用的每种资源(如HTML文档、图像、视频片段、程序等)都由一个URI进行定位。而人们平时使用的统一资源定位器(Uniform Resource Locator,URL)就是URI的一种实现。一个简单的URL由以下3部分组成:

用于访问资源的协议(如HTTP);

要与之通信的Web服务器的地址;

主机上资源的路径。

当图2-1中的Web服务器的IP地址为192.168.0.1时,用户可以使用http://192.168.0.1/index. html这个URL来获取上面的资源。这里的index.html就是主机上资源的路径。如图2-2所示,这个路径看起来有些复杂,但是实际上与主机操作系统的目录是相互关联的。

图2-1 放入Web服务器的静态文档

图2-2 将个人计算机作为Web服务器时的目录

这里以基于Windows操作系统的计算机为例,当其安装了Web服务器软件之后,就成为一个Web服务器。这个实例以Windows操作系统D盘下的WWW文件夹作为Web发布目录,并将其进行了映射,访问http://192.168.0.1/相当于在Windows操作系统下访问D:\WWW\。所以,用户同样可以使用http://192.168.0.1/Test/test1.htm访问计算机中的test1.htm文件。这里需要注意的是,Windows约定使用反斜线(\)作为路径中的分隔符,UNIX和Web应用则使用正斜线(/)作为路径中的分隔符。

Web服务器已准备完毕,现在切换到客户端。万维网的客户端就是常使用的各种浏览器(如火狐、Google Chrome等)。客户端的第一个功能是将用户的请求按照HTTP标准封装成报文发送给Web服务器,如图2-3所示。

Web服务器接收HTTP请求后,会对其进行解析,并将其请求的资源返回给客户端,如图2-4所示。

图2-3 按照HTTP标准封装成报文

图2-4 客户端与服务端之间的通信

HTTP的请求和应答都是以数据包的形式传输的,但是在浏览器中看到和操作的都是十分直观的图形化页面。这就要归功于客户端的第二个功能——解析Web服务器返回的HTTP应答,然后以常见的页面样式呈现出来,如图2-5所示。

图2-5 浏览器将HTTP应答解析为图形化页面

前面介绍的是静态Web应用程序的情形,在这个实例中Web服务器的工作是接收来自客户端的请求,对其解析后再将请求的资源以应答的方式返回给客户端。在这种情况下,服务器所面临的安全威胁主要来自操作系统(Windows和Linux操作系统等)和Web服务器程序(IIS和Apache等)的漏洞和错误配置等,而用HTML编写的静态页面本身并不存在任何漏洞。由于没有身份验证机制,Web服务器所发布的内容本身就允许被所有人所访问,同时也不会保存用户的任何信息,因此并不存在信息泄露的危险。在这种情况下,Web服务器的安全维护难度相对较小。攻击者所造成的破坏也只限于篡改 Web 应用程序页面,或者让Web应用程序服务器无法被访问。

随着万维网的发展,单纯使用静态技术的 Web 应用程序显得越来越无法满足使用者的需要,其主要缺陷如下。

扩展性极差,如果要修改Web应用程序,必须重新编写应用程序代码。

纯静态的Web应用程序存储信息时,所占用的空间相当大。

使用者只能对纯静态的Web应用程序进行读操作,无法实现交互。

其中最后一点是最为致命,试想一下,如果现在十分流行的购物Web应用程序(如淘宝)上只能展示商品信息,但是用户在客户端既不能下单购物,也不能对商品进行评论,那这个应用程序还会有这么大的影响力吗?

基于动态技术的Web应用程序的出现则有效解决了上述问题。动态技术需要使用专门的服务器端编程语言来实现,如PHP、JSP、ASP.net等。图2-6给出了一个使用PHP语言编写的简单动态Web应用程序。

图2-6 一个简单的动态Web应用程序

这时的Web服务端除了用来响应客户端请求的Web服务器软件之外,还需要一个专门用来处理服务器端编程语言的解释器,有时还会需要储存数据的数据库。由于Web应用程序采用的编程语言不同,服务器端的组织结构也有所不同。例如,使用PHP语言编写的动态Web应用程序的服务器端组织结构,如图2-7所示。

相比单纯的静态Web应用,动态Web应用程序中的网页实际上并不是独立存在于服务器上的网页文件。只有当用户请求时,Web服务器才会生成并返回一个完整的网页。这样既可以大大降低网站维护的工作量,还可以实现更多的功能。

但是PHP语言引擎、数据库和动态Web应用程序的加入,导致服务端遭受攻击的情况变得更加严重了,其中的重灾区就是动态Web应用程序。目前用来开发动态Web应用程序的语言就有数十种,仅国内就有数以百万计的动态Web应用程序发布到了互联网上,它们的代码质量参差不齐,其中不乏漏洞百出者。而动态Web应用程序本身的安全性往往又与程序员的个人能力息息相关。

图2-7 使用PHP语言编写的动态Web应用程序的服务端组织结构