> For the complete documentation index, see [llms.txt](https://mm.ricky.moe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mm.ricky.moe/network/liu-lan-qi/shu-ru-url-dao-ye-mian-jia-zai-fa-sheng-le-shen-me.md).

# 输入URL到页面加载发生了什么

## 概述

1. DNS解析
2. TCP连接
3. 发送HTTP请求
4. 服务器处理请求并返回HTTP报文
5. 浏览器解析渲染
6. 结束

![](/files/-LwX9yytnmY-2hXBp8ar)

## 具体

### DNS查询

![](/files/-LwX8taQ-9bSOrmzmlsx)

网址的解析是一个从右向左的过程: com -> google.com -> [www.google.com。但是你是否发现少了点什么，根域名服务器的解析过程呢？事实上，真正的网址是www.google.com.，并不是我多打了一个.，这个.对应的就是根域名服务器，默认情况下所有的网址的最后一位都是.，既然是默认情况下，为了方便用户，通常都会省略，浏览器在请求DNS的时候会自动加上，所有网址真正的解析过程为](https://mm.ricky.moe/network/liu-lan-qi/http:/www.google.com。但是你是否发现少了点什么，根域名服务器的解析过程呢？事实上，真正的网址是www.google.com.，并不是我多打了一个.，这个.对应的就是根域名服务器，默认情况下所有的网址的最后一位都是.，既然是默认情况下，为了方便用户，通常都会省略，浏览器在请求DNS的时候会自动加上，所有网址真正的解析过程为): . -> .com -> google.com. -> [www.google.com.。](http://www.google.com.。)

#### DNS缓存

DNS存在着多级缓存，从离浏览器的距离排序的话，有以下几种:&#x20;

* 浏览器缓存
* 系统缓存
* 路由器缓存
* IPS服务器缓存
* 根域名服务器缓存
* 顶级域名服务器缓存
* 主域名服务器缓存

#### DNS负载均衡

DNS可以返回一个合适的机器的IP给用户，例如可以根据每台机器的负载量，该机器离用户地理位置的距离等等，这种过程就是DNS负载均衡，又叫做DNS重定向。大家耳熟能详的CDN(Content Delivery Network)就是利用DNS的重定向技术，DNS服务器会返回一个跟用户最接近的点的IP地址给用户，CDN节点的服务器负责响应用户的请求。

### TCP连接

拿到了要请求的资源服务器IP后，浏览器通过操作OS的socket与服务器进行TCP连接（一般来说操作系统已经封装好了TCP/IP等协议，提供套接字给应用去使用。

* [x] 总结TCP三次握手

### HTTP请求与相应

在应用层，浏览器会分析这个url，并设置好请求报文发出。请求报文中包括请求行、请求头、空行、请求主体。https默认请求端口443， http默认80。

* **请求行**：请求行中包括请求的方法，路径和协议版本。
* **请求头**：请求头中包含了请求的一些附加的信息，一般是以键值的形式成对存在，比如设置请求文件的类型accept-type，以及服务器对缓存的设置。
* **空行**：协议中规定请求头和请求主体间必须用一个空行隔开
* **请求主体**：对于post请求，所需要的参数都不会放在url中，这时候就需要一个载体了，这个载体就是请求主题。

服务端收到请求之后，会根据url匹配到的路径做相应的处理，最后返回浏览器需要的页面资源。浏览器会收到一个响应报文，而所需要的资源就就在报文主体上。与请求报文相同，响应报文也有与之对应的起始行、首部、空行、报文主体，不同的地方在于包含的东西不一样。

* **响应行**：响应报文的起始行同样包含了协议版本，与请求的起始行不同的是其包含的还有状态码和状态码的原因短语。
* **响应头**：对应请求报文中的请求头，格式一致，但是各自有不同的首部。也有一起用的通用首部。
* **空行**
* **报文主体**：请求所需要的资源。

其中请求头与响应头有

* **Last-Modify(响应头) + If-Modified-Since（请求头）**
* **ETag（响应头） + If-None-Match（请求头）**
* **Cache-Control/Expires(响应头)**

### **页面渲染**

见[页面渲染](/network/liu-lan-qi.md)

### 连接关闭

现在的页面为了优化请求的耗时，默认都会开启持久连接（keep-alive），那么一个TCP连接确切关闭的时机，是这个tab标签页关闭的时候。这个关闭的过程就是著名的四次挥手。关闭是一个全双工的过程，发包的顺序的不一定的。一般来说是客户端主动发起的关闭

## 更详细的

1. 浏览器的地址栏输入URL并按下回车。
2. 浏览器查找当前URL是否存在缓存，并比较缓存是否过期。
3. DNS解析URL对应的IP。
4. 根据IP建立TCP连接（三次握手）。
5. HTTP发起请求。
6. 服务器处理请求，浏览器接收HTTP响应。
7. 渲染页面，构建DOM树。
8. 关闭TCP连接（四次挥手）。

![](/files/-Lwv1pxiL0PUPcFy-rr-)
