这是本系列文章的第二篇,前面的文章分别是:
全书探索之旅脉络图:
注:本系列文章旨在与大家探讨网络连接的全过程,因此会省略许多细节性问题,有兴趣的小伙伴可以阅读原著(强烈推荐!!!)
第一章 Web浏览器
1.1 生成 HTTP 请求消息
1.1.1 探索之旅从输入网址开始
网址,准确来说应该叫 URL,如果我 说它就是以 http:// 开头的那一串东西,恐怕大家一下子就明白了,但实际上除了“http:”,网址还可以以其他一些文字开头,例如“ftp:” “file:” “mailto:“等。
之所以有各种各样的 URL,是因为尽管我们通常是使用浏览器来访问Web 服务器的,但实际上浏览器并不只有这一个功能。浏览器是一个具备多种客户端功能的综合性客户端软件,因此它需要一些东西来判断应该使用其中哪种功能来访问相应的数据,而各种不同的URL就是用来干这个的,比如当访问 Web 服务器时应该使用 HTTPA 协议,而访问 FTP 服务器时则应该使用 FTP 协议。如下图:
1.1.2 浏览器先要解析 URL
浏览器要做的第一步工作就是对 URL 进行解析,从而生成发送给 Web服务器的请求消息。下面我们以访问 Web 服务器的情况为例来进行讲解。
根据 HTTP 的规格,URL 包含图 1.2(a)中的这几种元素。当对 URL进行解析时,首先需要按照图 1.2(a)的格式将其中的各个元素拆分出来, 例如图 1.2(b)中的 URL 会拆分成图 1.2(c)的样子。然后,通过拆分出来的这些元素,我们就能够明白 URL 代表的含义。例如,我们来看拆分结果图 1.2(c),其中包含 Web 服务器名称 www.lab.glasscom.com,以及文件的路径名 /dir1/file1.html,因此我们就能够明白,图 1.2(b)中的 URL 表示要访问 www.lab.glasscom.com 这个 Web 服务器上路径名为 /dir/file1.html 的文件,也就是位于 /dir/ 目录 下的 file1.html 这个文件(图 1.3)。
实际上除了1.2(b)中这种最后带上文件名的URL外,我们会发现平时访问的许多URL最后并没有带文件名,这时候会根据服务器上事先设置好文件名省略时要访问的默认文件名,大多数情况下是 index.html 或default.htm 之类的文件名。对具体细节有兴趣的小伙伴可以自己去了解一下。
1.1.3 HTTP 的基本思路
解析完 URL 之后,我们就知道应该要访问的目标在哪里了。接下来,浏览器会使用 HTTP 协议来访问 Web 服务器,不过在介绍这一环节之前,我们先来讲一讲 HTTP 协议到底是怎么回事。
HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤,其基本思路非常简单。首先,客户端会向服务器发送请求消息(图 1.4)。请求 消息中包含的内容是“对什么”和“进行怎样的操作”两个部分。其中相当于“对什么”的部分称为URI。一般来说,URI 的内容是一个存放网页数据的文件名或者是一个 CGI 程序的文件名。换句话说就是,这里可以写各种访问目标,而这些访问目标统称为 URI。
相当于接下来“进行怎样的操作”的部分称为方法。方法表示需要让 Web 服务器完成怎样的工作,其中典型的例子包括读取 URI 表示的数据、 将客户端输入的数据发送给 URI 表示的程序等。表 1.1 列举了主要的方法, 通过这张表大家应该能够理解通过方法可以执行怎样的操作。
除了图 1.4 中的内容之外,HTTP 消息中还有一些用来表示附加信息的头字段。客户端向 Web 服务器发送数据时,会先发送头字段,然后再发送数据。这里留到后面再讲。
收到请求消息之后,Web 服务器会对其中的内容进行解析,通过 URI 和方法来判断“对什么” “进行怎样的操作”,并根据这些要求来完成自己的工作,然后将结果存放在响应消息中。在响应消息的开头有一个状态码,它用来表示操作的执行结果是成功还是发生了错误。当我们访问 Web 服务器时,遇到找不到的文件就会显示出 404 Not Found 的错误信息,其实这就是状态码。状态码后面就是头字段和网页数据。响应消息会被发送回客 户端,客户端收到之后,浏览器会从消息中读出所需的数据并显示在屏幕上。到这里,HTTP 的整个工作就完成了。
推荐大家去看一看表 1.1 中所有方法的说明,思考一下它们的含义,以便理解 HTTP 协议具备的所有功能。
1.1.4 生成 HTTP 请求消息
URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。
首先,请求消息的第一行称为请求行。这里的重点是最开头的方法,方法可以告诉 Web 服务器它应该进行怎样的操作。值得注意的是,我们的场景是在地址栏中输入网址并显示网页,因此这里应该使用 GET方法。写好方法之后,加一个空格,然后写 URI。URI 部分的格式如下,一般是文件和程序的路径名。第一行的末尾需要写上 HTTP 的版本号,这是为了表示该消息是基于哪个版本的 HTTP 规格编写的。到此为止,请求行就结束了。
第二行开始为消息头。消息头的规格中定义了很多项目,如日期、客户端支持的数据类型、语言、压缩格式、客户端和服务器的软件名称和版本、数据有效期和最后更新时间等。主要的头字段有很多,但不必全部弄明白。消息头中的内容随着浏览器类型、版本号、设置等的不同而不同,大多数情况下消息头的长度为几行到十几行不等。
写完消息头之后,还需要添加一个完全没有内容的空行,然后写上需要发送的数据。这一部分称为消息体,也就是消息的主体。不过,在使用GET 方法的情况下,仅凭方法和 URI,Web 服务器就能够判断需要进行怎样的操作,因此消息体中不需要填写任何数据(当使用 POST 方法时,需要将表单中填写的信息写在消息体中)。到此为止,请求消息的生成操作就全部完成了。
1.1.5 发送请求后会收到响应
当我们将上述请求消息发送出去之后,Web 服务器会返回响应消息。关于响应消息我们将在第 6 章详细介绍,这里先粗略地了解一下。响应消息的格式以及基本思路和请求消息是相同的,差别只在第一行上。
在响应消息中,第一行的内容为状态码和响应短语,用来表示请求的执行结果是成功还是出错。状态码和响应短语表示的内容一致,但它们的用途不同。状态码是一个数字,它主要用来向程序告知执行的结果(表1.3);相对地,响应短语则是一段文字,用来向人们告知执行的结果。
返回响应消息之后,浏览器会将数据提取出来并显示在屏幕上,我们就能够看到网页的样子了。如果网页的内有文字,那么到这里就全部处理完毕了,但如果网页中还包括图片等资源,则还有下文。
当网页中包含图片时,会在网页中的相应位置嵌入表示图片文件的标签(img标签)的控制信息。浏览器会在显示文字时搜索相应的标签,当遇到图片相关的标签时,会在屏幕上留出用来显示图片的空间,然后再次访问 Web 服务器,按照标签中指定的文件名向 Web 服务器请求获取相应的图片并显示在预留的空间中。这个步骤和获取网页文件时一样,只要在 URI 部分写上图片的文件名并生成和发送请求消息就可以了。
由于每条请求消息中只能写 1 个 URI,所以每次只能获取 1 个文件,如果需要获取多个文件,必须对每个文件单独发送 1 条请求。这一系列工作的整体指挥也是浏览器的任务之一,而 Web 服务器却毫不知情,Web 服务器只会根据请求返回数据。
到这里,我们已经介绍了浏览器与 Web 服务器进行交互的整个过程。作为参考,图 1.7 展示了浏览器与 Web 服务器之间交互消息的一个实例。在这个例子中,我们需要获取一张名为 sample1.htm 的网页,网页中包含一张名为 picture.jpg 的图片,图中展示了这个过程中产生的消息。
小结
以上就是第一章第一节生成 HTTP 请求消息的全部内容,其中讲到了URL解析后的各部分含义、讲到了什么是HTTP协议、讲到了HTTP请求消息的生成及其组成(请求行、消息头、消息体)、讲到了HTTP响应消息的生成及其组成(响应行、消息头、消息体),最后讲到了浏览器获取到服务器返回的响应后,对响应消息进行渲染的过程。
本期的整理就先到这里啦,我们下一期见!!!