「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」
往期文章
网络是怎样连接的(一)—— 浏览器访问 Web 服务器过程概览
前言
今天开始我们网络学习的第二节,学习内容主要分为两大部分:
- 浏览器是如何对 URL 进行解析;
- 浏览器是如何生成 HTTP 消息并将消息发送出去;
虽然说是解析 URL 并生成 HTTP 消息,但是实际上 URL 除了有 http
开头,还有 ftp
、file
、mailto
开头的 URL。之所以有各种各样的 URL,是因为尽管我们通常是使用浏览器来访问 Web 服务器的,但实际上浏览器并不只有这一个功能,它也可以用来在 FTP 服务器上下载和上传文件,同时也具备电子邮件客户端的功能。可以说,浏览器是一个具备多种客户端功能的综合性客户端软件,因此它需要一些东西来判断应该使用其中哪些功能来访问响应的数据,而各种不同的 URL 就是用来干这个的,比如访问 Web 服务器时用 http,而访问 FTP 服务器时用 ftp。
今天我们主要以 HTTP 开头的 URL 为例,来探索网络连接过程。
URL 解析
URL 格式
浏览器第一步要做的就是解析 URL。因此我们先要了解下 URL 的结构组成。我们以百度百科的 URL 为例来说明:
https://baike.baidu.com/item/URL%E6%A0%BC%E5%BC%8F/10056474
URL 由三部分组成:资源类型、存放资源的主机域名、资源文件名
也可认为由四部分组成:协议、主机、端口、路径
URL 的一般语法格式为(带方括号 []
的为可选项):
protocal://hostname[:port]/path/[:parameters][?query]#fragment
protocal
(协议) :指定使用的传输协议,如https
。hostname
(主机名) :指存放资源的服务器的域名系统(DNS)主机名或 IP 地址,如baike.baidu.com
。port
(端口号) :可选,省略时使用方案的默认端口,如 http 的默认端口为80
。path
(路径) :由零或多个/
符号隔开的字符串,用来表示主机上的一个目录或文件地址,如item/URL%E6%A0%BC%E5%BC%8F/10056474
。query
(查询) :可选,用于给动态网页传递参数,比如我们常见的 API。fragment
(信息片段) :用于指定网络资源中的片段,比如文章中每个「一级标题」对应一个片段。
常见的协议有如下几种:
协议 | 格式 | 解释 |
---|---|---|
http | http:// | 通过 HTTP 访问该资源。 |
https | https:// | 通过安全的 HTTPS 访问该资源。 |
ftp | ftp:// | 通过 FTP 访问资源。 |
file | file:/// | 资源是本地计算机上的文件。注意后边应是三个斜杠。 |
mailto | mailto: | 资源为电子邮件地址,通过 SMTP 访问。 |
mms | mms:// | 通过 支持 MMS(流媒体)协议的播放该资源。 |
URL path 部分说明
上面我们已经看过了 URL 的格式,实际上,对于 path
部分,可能会有部分省略,比如下面几个场景。
(a) https://baidu.com/dir1/file1.html // 典型 URL
(b) https://baidu.com/dir1/ // 以 / 结尾,省略文件名
(c) https://baidu.com/ // 以 / 结尾,省略目录名
(d) https://baidu.com // 省略所有,只有域名
(e) https://baidu.com/name1 // 没有 / 结尾,不确定是目录还是文件
对于 (b)
场景,以 /
结尾表示 dir1
后面的文件名被省略,那么服务器这时会访问默认文件名,大多数情况下是 index.html
或 default.htm
之类的文件名。
对于 (c)
场景,同理,只不过访问的不是 dir1
目录下的默认文件,而是 /
目录下的默认文件。
对于 (d)
场景,则表示的是根目录下的默认文件。
对于 (e)
场景,由于没有 /
,我们不确定这代表的是文件名还是目录名,此时服务器处理的逻辑是,如果存在 name1
的文件名,则访问该文件,否则按照目录来处理,来寻找 name1
目录下的默认文件。
URL 解析
浏览器根据 URL 规则,解析 URL。
生成 HTTP 消息
HTTP 协议概述
浏览器在解析完 URL 之后,我们就知道应该要访问的目标在哪里了。接下来,浏览器会使用 HTTP/HTTPS 协议来访问 Web 服务器。我们先来简单了解下 HTTP 协议到底是怎么回事。
HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤,其基本思路非常简单。首先,客户端会向服务器发送请求消息。请求消息中包含的内容是“对什么”和“进行怎样的操作”两个部分。其中相当于“对什么”的部分称为 URI。一般来说,URI 的内容是一个存放网页数据的文件名或者是一个 CGI 程序的文件名。
相当于接下来“进行怎样的操作”的部分称为方法。方法表示需要让 Web 服务器完成怎样的工作,其中典型的例子包括读取 URI 表示的数据、将客户端输入的数据发送给 URI 表示的程序等。常用的方法有 GET
、POST
,其他方法如 PUT
、HEAD
、OPTIONS
、DELETE
等。
收到请求消息之后,Web 服务器会对其中的内容进行解析,通过 URI 和方法来判断“对什么”“进行怎样的操作”,并根据这些要求来完成自己的工作,然后将结果存放在响应消息中。在响应消息的开头有一个状态码,它用来表示操作的执行结果是成功还是发生了错误。
生成 HTTP 消息
对 URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。HTTP 的请求消息和响应消息的格式是固定的。我们先来看一下请求结构体的具体示例。
GET /list_api/v1/annual/user_annual HTTP/1.1
Accept: */*
Referer: https://api.juejin.cn
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Host: xxx.xxx.xxx.xxx
Connection: Keep-Alive
Cookie: startupapp=neo; is_cisco_platform=0; rdx_pagination_size=250%20Per%20Page; SESSID=deb31b8eb9ca68a514cf55777744e339
HTTP 请求格式如下:
请求头 空格 URL 空格 协议版本 回车符 换行符 // 请求行
头部字段名:值 回车符 换行符 // 请求头部
.
.
.
头部字段名:值 回车符 换行符 // 请求头部
回车符 换行符
xxxxxxxxxxxxxxx // 请求数据
首先,请求消息的第一行称为请求行。这里的重点是最开头的方法,方法可以告诉 Web 服务器它应该进行怎样的操作。 一般情况下,不同的场景采用的方法也不一样,比如浏览器输入 URL 会采用 GET
方法,表单输入会采用 POST
方法。
对于不同的方法,消息体的格式也不尽相同。准确来说,消息体的格式会通过消息头中的 Content-Type
字段来定义。浏览器和 Web 服务器会根据此格式来生成消息。
写好方法之后,加一个空格,然后写 URI。URI 部分的格式一般如下:/目录名/.../文件名
。前面已经讲过,路径名一般来说已经包含在 URL 中了,因此只要从 URL 中提取出来原封不动地写上去就好了。
第一行的末尾需要写上 HTTP 的版本号,这是为了表示该消息是基于哪个版本的 HTTP 规格编写的。
第二行还是为消息头。 尽管通过第一行我们就可以大致理解请求的内容,但有些情况下还需要一些额外的详细信息,而消息头的功能就是用来存放这些信息。
写完消息头之后,还需要添加一个完全没有内容的空行,然后写上需要发送的数据。这一部分称为消息体,也就是消息的主体。
获取 HTTP 响应数据
当我们将上述请求消息发送出去之后,Web 服务器会返回响应消息。
响应消息的格式以及基本思路和请求消息是相同的,差别只在第一行上。在响应消息中,第一行的内容为 状态码和响应短语,用来表示请求的执行结果是成功还是出错。状态码和响应短语表示的内容一致,但它们的用途不同。状态码是一个数字,它主要用来向程序告知执行的结果;相对地,响应短语则是一段文字,用来向人们告知执行的结果。
返回响应消息之后,浏览器会将数据提取出来并显示在屏幕上,我们就能够看到网页的样子了。(文字类型,如果还包含图片,会更复杂些)
总结
上面内容中,我们介绍了浏览器解析 URL 并生成 HTTP 消息的部分细节,相信我们对浏览器输入 URL 并敲下回车的第一步已经有一个初步的概念。下一篇内容,让我们学习下系统是如何根据 HTTP 消息内容将消息发送给服务器。
希望能给大家带来帮助!
参考文档
- 《网络是怎样连接的》—— 户根勤
- URL格式