浏览器输入地址后,发生了什么
huan

整体流程:
image

URL解析

首先第一步,需要对url进行解析,通常来说,url 包含 协议、域名、端口、资源路径、参数
例如:https://pro.jd.com/mall/active/hEFfzNmUqhjLxLgGCcpbDXSMYkP/index.html?babelChannel=ttt49
协议:https,常见的还有 http、ftp 等
域名:pro.jd.com,其中.com是顶级域名,jd是一级域名,pro是二级域名
端口:https默认端口是 443,http 默认端口是80,默认值可以省略
资源路径:/mall/active/hEFfzNmUqhjLxLgGCcpbDXSMYkP/index.html,默认是 index.html
参数:? 之后的为参数,babelChannel 为 ttt49,如果多个参数用 & 拼接,比如 name=tom&age=12

https 即 http 的加密扩展,通过非对称加密的方式,来保障数据的加密传输、身份验证、数据完整性等功能,保护网络安全

常见顶级域名还有 .cn 、.net 、.gov(政府)、.edu(教育) 等等

如果端口不是默认端口,则写成 http://xxxx.com:8080/

域名解析

解析出域名之后,需要对域名对应的 ip 地址进行解析,才能知道目标的资源,在哪台机器上。这里得到的 ip 通常是公网的
image
简单来说,浏览器询问 DNS 服务器,我想知道的域名,对应的地址是多少。可以理解为在 DNS 服务器上存在这样的一张表,里面包含了域名和 ip 的解析。

域名 ip
jd.com 211.144.27.126
pro.jd.com 106.39.170.41
search.jd.com 136.29.120.23

在我们自己的电脑上,经常会用 ping 的方式来测试和某个地址是否可以触达,如果我们 ping 的是域名,也可以达到域名解析的效果:

1
2
3
4
 ~ → ping pro.jd.com                             
PING pro.jd.com.gslb.qianxun.com (106.39.170.41): 56 data bytes
64 bytes from 106.39.170.41: icmp_seq=0 ttl=48 time=33.205 ms
64 bytes from 106.39.170.41: icmp_seq=1 ttl=48 time=33.680 ms

通常浏览器域名解析的结果和很多个因素有关,比如浏览器缓存、本地 hosts 文件、路由器/交换机上的缓存、DNS服务器的配置等等。比如说,修改本地 hosts 中 pro.jd.com 对应的 ip 地址,ping 之后会得到你设置的结果:

1
2
3
4
5
6
7
8
9
 ~ → sudo vi /etc/hosts

127.0.0.1 pro.jd.com # 添加这一行

~ → ping pro.jd.com
PING pro.jd.com (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.035 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.052 ms

域名是在域名提供商处(比如阿里云万网)购买的,然后设置域名解析到一个公网 ip 上,就在 DNS 服务器上注册好了。域名就可以正常解析。

建立TCP连接

得到域名对应的目标 ip 之后,浏览器通过计算机开始在茫茫大海中寻找目标的 ip 对应的服务器,经过一段时间的寻找之后,就开始了和服务器的握手。
http / https 是给予 TCP 的可靠的连接,需要经过 TCP 的三次握手

为什么一定得是可靠的连接呢?想象一下,如果这个连接不可靠,可能就会出现网页乱码、图片只展示一半的情况

image
这个过程是:

  1. 客户端发送 SYN 请求给服务端,携带参数 seq num,来标示这一个请求在客户端上的 id
  2. 服务器收到之后,回应 ACK,并且发送 SYN,携带参数 ack num 为 客户端seq num +1,并且发送服务端的 seq num
  3. 客户端收到服务器的 SYN 之后,回复ACK,并且把收到的 seq num + 1 发送给服务器

用两个人打电话来举例,简单这个过程:

  1. A 对 B 说:喂,能听到吗?;(A 测试自己说话是否对方可以听到)
  2. B 对 A 说:诶,我能听到,你能听到我的话吗?(B 听到了A 说的话,但是B 不知道自己说的话A 能不能听到)
  3. A 说:可以听到(A 能听到 B 说话,同时因为B 回复了A 的第一句话,所以对于A 来说连接已经建立了)
  4. B 听到了A 说的话之后,就知道他们之间的对话是顺畅的。此时两人就建立连接了

发送HTTP请求

常见的 http 请求有这么多:

  1. GET,最常见的用来打开网页、获取数据。从地址栏、超链接等方式打开的页面,都属于这种
  2. POST,一般用来提交数据,比如说登陆注册、提交订单、付款、发动态
  3. PUT,修改数据,比如修改密码
  4. DELETE,用来删除数据
  5. PATCH、HEAD、OPTIONS 等等

但是这些只是规范,日常开发很可能出现混用的场景

处理请求

服务器收到了浏览器的请求之后,通常会对请求进行验证。比如:协议是否正确、请求方式是否可接受、是否需要登陆等
然后根据不同的请求类型,对请求进行处理。如果请求的是文件,则根据资源路径在服务器上寻找这个文件。如果是一个后端的接口,则执行接口对应的业务逻辑

发送HTTP响应

当服务器找到了浏览器所需要的资源的时候,就会把响应数据发送给浏览器。可能是一张图片、一个网页、一段 js 代码、或者是json 数据等等
例如,返回这样一段html代码,其中包含了 css 、 js 、图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 引入css -->
<link rel="stylesheet" href="./styles.css">
<!-- 引入js -->
<script src="./script.js" defer></script>
<!-- 网页标题 -->
<title>My Web Page</title>
</head>
<body>
<!-- 显示标题 -->
<h1>Hello, World!</h1>
<!-- 引入图片 -->
<img src="./image.jpg" alt="An example image">
</body>
</html>

渲染页面

浏览器拿到服务器响应的数据之后,就会对数据进行处理,以网页为例,一个完整的网页包含以下内容

  1. html:页面的骨架,决定了这个页面存在哪些元素
  2. css:页面样式,规定了页面上的元素位置、大小、颜色等
  3. javaScript(js):浏览器可以执行的代码脚本

首先,浏览器根据 html 的内容,得到页面;
然后,再看这个 html 中有没有引用 css,如果有,则加载,运行 css,对页面进行渲染;如果页面引入了 js,则加载,运行,js 可以对页面上的元素进行修改,或者是动态加载一些内容;
最后,页面就会被完整展示出来,如果页面中用到了图片、视频等多媒体资源,则继续加载,渲染
比如刚服务器返回的代码,渲染出来就是这样的:
image

断开TCP连接

对于一个连接来说,如果到了设置的存活时间,就会自动向服务器断开TCP连接。一个客户端可能连接了几百上千个不同的服务器,一个服务器上连了几万个、十万个连接,如果不及时释放,资源会被消耗完,所以释放连接是一个非常必要的操作
image
在这个图中,是客户端主动发起的,这个过程是:

  1. 客户端(主动发起方)发送 FIN,表示没有更多数据要发送了,准备关闭连接
  2. 服务端(被动关闭方)回复 ACK,确认收到 FIN,此时也准备关闭了
  3. 由于服务端可能还有数据需要发送,所以等待数据发完后,发送自己的 FIN 给客户端,表示自己数据都发完了,可以关闭连接了
  4. 客户端收到后,回复 ACK,表示收到服务端发的 FIN,然后服务端就 CLOSE 了
  5. 经过一段时间后,通常为2倍最大报文生存时间(2MSL)之后,客户端也关闭连接

    最后一步,为什么要等待 2MSL 时间呢?客户端需要确保自己的 ACK 服务端已经收到了,如果服务端没有收到,会再次发送 FIN,客户端仍需要处理

http状态码

当浏览器与服务器之间进行通信时,HTTP状态码是服务器向客户端返回的一个三位数字代码,用于表示请求的处理状态。这些状态码提供了关于请求结果的信息,帮助客户端和开发者理解发生的情况。

1xx - 信息性响应,没有实际的结果

  • 100:客户端可以继续发送请求

2xx - 成功处理

  • 200 OK: 表示请求已成功,服务器返回了所请求的数据。
  • 201 Created: 表示服务器成功创建了新资源。
  • 204 No Content: 表示请求已成功处理,但响应中没有返回任何内容。

3xx - 重定向响应

  • 301 Moved Permanently: 请求的资源已永久移动到新位置,客户端应更新其链接。
  • 302 Found (Moved Temporarily): 请求的资源已临时移动到新位置。
  • 304 Not Modified: 表示资源未修改,客户端可以使用缓存的版本。

4xx - 客户端错误响应

  • 400 Bad Request: 表示服务器无法理解请求,比如参数错误。
  • 401 Unauthorized: 表示请求需要身份验证,比如登陆过期
  • 403 Forbidden: 表示服务器拒绝请求,客户端没有权限访问资源。
  • 404 Not Found: 请求的资源不存在,比如地址错误、id 错误等
  • 405 Method Not Allowed: 请求方法不被允许,比如 POST 接口用 GET 方式访问。
  • 429 Too Many Requests: 客户端发送的请求过多,被服务器限制。

5xx - Server Error Responses (服务器错误响应):

  • 500 Internal Server Error: 表示服务器内部错误,通常是代码原因。
  • 502 Bad Gateway: 表示服务器网关错误。
  • 503 Service Unavailable: 表示服务器暂时无法处理请求,通常是由于过载或服务挂了。