写在前面
在浏览器地址栏输入URL会发生什么?主要是网络传输资源和浏览器渲染两部分。其中,浏览器的渲染机制部分早已写好,欢迎食用👏👏
接下来,本文将从计算机网络层面梳理该部分内容(基于建立连接的网络请求过程)。
正文
解析URL(统一资源定位符)
URL用于定位目标服务器上的资源。解析URL之前,我们需要知道URL可以分为几部分,下面以 www.example.com:80/path/index.… 为例。
1.https - 方案(scheme)
我们常说的超文本传输协议是一种方案,在上述样例URL中,https表示必须通过https这种方案来请求网络资源,它的非安全版本是http。
二者的安全体现在加密方式上,http是一种未加密的超文本传输协议,而https则是结合对称加密和非对称加密的传输协议。
2.www.example.com - 域名(domain)
域名就是服务器地址(IP)的别名,例如本机地址是:127.0.0.1。但是为了更方便记忆,会使用localhost当成IP地址的代名词,也就是域名。
3.80 - 端口(port)
端口是访问服务器具体资源的入口。
只有传输协议 域名 端口三个内容相同的对象,才会被浏览器视为同源。
4./path/index.html - 资源路径(path)
在web发展早期,资源路径是远程服务器上对应资源的物理位置。
5.?value=20 - 路径参数(params)
资源路径参数通常是以&分割的键-值对,用于Web服务器在返回资源前的一些操作。
6.#anchor - 锚点(anchor)
锚点是URL的最后一部分,相当于一个页面的书签。
一、DNS(Domain Name System)域名系统解析
域名虽然符合人类的记忆习惯,但是对于浏览器来说,IP地址来的更直接。所以,在请求远程Web服务器的资源前,浏览器需要先找到域名对应的IP地址。
具体找法如下:
- 在本地域名服务器
缓存中查找域名对应的ip地址。 - 如果上一步未找到,则去
根域名服务器查找。 - 如果上一步未找到,则去(com)
顶级域名服务器查找。 - 如果上一步未找到,则去
权威域名服务器查找,这里是最终保存域名对应IP地址的服务器。
在这个过程中,每个参与了查询的服务器都会缓存一份结果。最后,浏览器也会将得到的对应IP地址写入本地DNS缓存。
二、基于TCP协议建立网络连接
TCP是传输控制协议,深入挖掘底层涉及到网络传输模型等内容,这里不做详细讲解。
要进行网络资源传输,建立连接是稳定、可靠的做法。基于TCP建立连接主要就是经历三次握手。
这里我们以客户端和服务端为对象说明:
三次握手
- 第一次握手,客户端向服务端发送建立连接的请求,客户端进入
SYN_SEND状态。 - 第二次握手,服务端接收到了客户端的建立连接请求后,返回同意连接的应答,服务端进入
SYN_RECEIVED状态。 - 第三次握手,客户端接收到了服务端的应答后,再次发送确认接收到响应的应答,客户端、服务端都进入
ESTABLISHED状态(已确立)。
也就是一请求,一应答,再是应答的应答。像不像你和女朋友说拜拜的场景:
你:拜拜👋
她:拜拜,我会xxxxx
你:我也xxxxx
嗯,没错!有内味了。
但是这个逻辑放在建立连接当中是不是有点不太合适呢?为什么要有第三次握手,两次行不行?
📒回答:
不行,因为第三次握手是客户端向服务端确认接收到回复的应答,表明服务器可以开始传输数据了。
如果只是两次握手,服务端有可能进入无效等待。如果在第一次握手时,客户端第一次发送的SYN数据包在失效前刚好到达了服务端,服务端依旧会响应一个SYN_ACK包给客户端,但是客户端此时可能已经关闭了连接,导致服务端一直收不到应答,一直在等待客户端的回复。
三、基于超文本传输协议传输数据
HTTP是客户端--服务端的一个无状态协议,这表明服务器不会保留两端请求的任何数据。我们可以将HTTP请求抽象地看成是一个实体,一个基于代理(proxy)的实体。
- 请求行(Request Line)
-
请求行包含了三个主要的部分:
- 请求方法(Method) :指示了希望对资源执行的操作,常见的有
GET、POST、PUT、DELETE、HEAD等。 - 请求URI(Uniform Resource Identifier) :标识了请求的目标资源,通常是一个路径名或文件名,也可以是完整的 URL。
- HTTP 版本:指定了使用的 HTTP 协议版本,如
HTTP/1.1或HTTP/2。
例如:
GET /index.html HTTP/1.1 - 请求方法(Method) :指示了希望对资源执行的操作,常见的有
- 请求头(Request Headers)
-
请求头包含了多个字段,每个字段由一个关键字和一个值组成,用来传递客户端和服务器之间的元数据。
-
一些常见的请求头包括:
-
Host: 指定被请求的服务器主机名或 IP 地址。 -
User-Agent: 描述了发出请求的客户端软件的信息。 -
Accept: 表明客户端能够接受哪些类型的内容。 -
Accept-Language: 表示客户端首选的语言。 -
Accept-Encoding: 指出客户端能够理解的内容编码方式,如 gzip 压缩。 -
Authorization: 包含认证信息。 -
Cookie: 包含客户端的 cookie 信息。 -
请求头的各个字段之间以回车换行符分隔,并且整个头部以一个额外的空行结束。
-
例如:
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
3. 空行(Blank Line)
- 空行是一个单独的行,用来分隔请求头和请求体。
- 请求体(Request Body)
- 请求体是可选的,只存在于某些类型的请求中(例如
POST、PUT)。请求体包含了要发送给服务器的数据,比如表单提交的数据或者 API 调用中的参数。 - 在
POST请求中,请求体通常包含了用户输入的数据。 - 请求体的数据类型可以通过
Content-Type头部字段来指定。 例如,对于一个表单提交的POST请求:
username=johndoe&password=secret
四、服务端解析请求生成HTTP响应
服务端解析请求后会返回对应响应数据。
1.状态行(Status Line)
- HTTP 版本:指定了使用的 HTTP 协议版本,如
HTTP/1.1或HTTP/2。 - 状态码:表示请求的结果,常用的有
200 OK、404 Not Found、500 Internal Server Error等。 - 状态消息:对状态码的简短描述,如
OK、Not Found等。这个部分是可选的,但在实践中几乎总是存在。
例如:
HTTP/1.1 200 OK
2.响应头(Response Headers)
响应头包含了多个字段,每个字段由一个关键字和一个值组成,用来传递服务器和客户端之间的元数据。这些元数据可以用于帮助客户端处理响应。
一些常见的响应头包括:
Content-Type:指定了响应体的媒体类型,如text/html、application/json等。Content-Length:指定了响应体的长度(以字节为单位)。Date:指定了响应生成的时间。Server:描述了服务器软件的信息。Set-Cookie:用于设置客户端的 cookie。Cache-Control:用于控制缓存行为。Expires:指定了响应何时过期。Content-Encoding:指定了内容的编码方式,如gzip或deflate。
例如:
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
Date: Sat, 24 Aug 2024 22:04:00 GMT
Server: Apache/2.4.41 (Ubuntu)
Set-Cookie: sessionId=abc123; Max-Age=3600; HttpOnly
Cache-Control: max-age=3600
Expires: Sat, 24 Aug 2024 23:04:00 GMT
3. 空行(Blank Line)
空行是一个单独的行,用来分隔响应头和响应体。
- 响应体(Response Body)
响应体是可选的,包含了服务器返回给客户端的实际内容。例如,如果请求的是一个 HTML 页面,响应体将包含 HTML 内容;如果请求的是 JSON 数据,响应体将包含 JSON 格式的数据。
五、断开TCP连接
当客户端完成接收来自服务端的数据后可能会断开连接,服务端响应的也可能会断开连接,特别是在收到来自客户端的FIN包后。断开TCP连接的过程被称为四次挥手。
-
第一次挥手:客户端向服务器发送断开连接请求。
-
第二次挥手:服务器接收到断开请求后,向客户端返回同意断开的响应,并进入
CLOSE_WAIT状态。 -
第三次次挥手:如果服务器还有未发送的数据,会继续发送给客户端。发送完之后,服务器进入
LAST_ACK状态。 -
第四次挥手:客户端向服务器发送确认应答,并进入
CLOSE_WAIT状态,持续时间为 2MSL。服务器接收到客户端的应答后,进入CLOSED状态。在 2MSL 时间后,客户端自动进入CLOSED状态。
其他
后续就是浏览器解析资源的步骤,准备渲染页面。不过,为了让用户更快地浏览页面,浏览器可能会在TCP连接完全断开之前去渲染页面,只要资源是足够的,这取决于浏览器的渲染机制。
总结
浏览器解析URL的前半部分可以分为:
- DNS解析
- 建立TCP连接(三次握手)
- 基于传输协议的数据传输
- 随请求发送
- 随响应返回
- 断开连接(四次挥手)
当然,还有后半部分:
- 解析HTML
- 解析CSS
- 生成渲染树
- 计算布局
- 元素分层
- 绘制图像
- 合成页面
具体见: 我有一颗复杂的心,很少人能读懂。-- 浏览器内核篇(一)
后续打算围绕HTTP协议的发展写一篇文章,下期见。