大概流程
- 1、输入URL
- 2、浏览器缓存查找当前URL
- 3、DNS解析URL
- 4、建立TCP连接(三次握手)
- 5、HTTP发起请求
- 6、服务器处理请求,浏览器接收HTTP响应
- 7、关闭TCP连接(四次挥手)
- 8、渲染页面,构建DOM树
1、输入URL
URL(Uniform Resource Locator)是用于定位和标识互联网资源的地址。它由多个组成部分组成,用于指定资源的位置和访问方式。下面是URL的详细解释和各个组成部分的说明:
eg:http://www.example.com:80/path/to/resource?query=string#fragment
-
协议(Protocol):在URL的开头部分,用于指定访问资源所使用的协议。常见的协议包括:
- HTTP(超文本传输协议):用于在Web浏览器和Web服务器之间传输数据。
- HTTPS(安全超文本传输协议):通过SSL或TLS协议对HTTP进行加密,提供安全的数据传输。
- FTP(文件传输协议):用于在客户端和服务器之间传输文件。
- SMTP(简单邮件传输协议):用于发送电子邮件。
- 等等。
-
主机名(Host):主机名指示要访问的服务器的域名或IP地址。在示例中,主机名是"www.example.com"
-
端口(Port):可选项,指定要连接到的服务器上的端口号。如果未指定,默认使用协议的默认端口号。在示例中,端口是":80",表示使用HTTP协议的默认端口。
-
路径(Path):指定服务器上资源的路径或文件名。在示例中,路径是"/path/to/resource"。
-
查询字符串(Query String):可选项,用于向服务器传递参数或数据。它以"?"符号开始,参数之间使用"&"分隔。在示例中,查询字符串是"?query=string"。
-
片段标识(Fragment):可选项,指定文档中的特定片段或锚点。它以"#"符号开始。在示例中,片段标识是"#fragment"。
2、浏览器缓存查找当前URL
浏览器缓存是指浏览器在本地存储已经访问过的资源副本,以便在后续的请求中可以更快地获取这些资源。通过使用缓存,浏览器可以避免重新下载相同的资源,从而提高页面加载速度,减少网络流量和服务器负载。
浏览器缓存可以分为两种类型:强缓存和协商缓存。
- 强缓存:强缓存是通过在HTTP响应头中设置一些参数来控制的,使得浏览器可以在本地缓存中直接获取资源,而不需要向服务器发送请求。常见的强缓存相关的响应头字段包括:
Cache-Control:该字段用于指定缓存策略。常见的取值包括:
- public:表示响应可以被任何缓存(包括客户端和代理服务器)缓存。
- private:表示响应只能被客户端缓存,而不能被代理服务器缓存。
- no-cache:表示缓存服务器不能直接使用缓存的响应,而是需要先向源服务器验证该资源是否仍然有效。
- max-age=<seconds>:表示缓存的有效期,即资源在缓存中保存的时间(以秒为单位)。
- s-maxage=<seconds>:类似于max-age,但仅适用于共享缓存(如代理服务器)。
Expires:该字段指定了一个绝对的过期时间,表示资源在此时间之后被认为是过期的。值是一个HTTP日期格式的字符串。
-
协商缓存:协商缓存是通过与服务器进行通信来确定是否可以使用缓存的资源副本。当浏览器发送请求时,服务器会返回一些响应头字段,用于标识资源的标识符和相关的缓存信息。如果浏览器在本地缓存中有相应的资源副本,它会与服务器提供的信息进行比较,以确定是否可以使用缓存的副本。常见的协商缓存相关的响应头字段包括:
- Last-Modified:指示资源的最后修改时间。
- If-Modified-Since:当浏览器再次请求资源时,会将上次的Last-Modified值通过该字段发送给服务器,服务器可以根据该值判断资源是否有变化。
- ETag:指示资源的唯一标识符,可以是资源内容的哈希值等。
- If-None-Match:当浏览器再次请求资源时,会将上次的ETag值通过该字段发送给服务器,服务器可以根据该值判断资源是否有变化。
当浏览器判断可以使用缓存时,它会直接从本地缓存中获取资源,并且不会发送请求到服务器。如果缓存失效或需要重新验证资源是否过期,浏览器会发送请求到服务器,并根据服务器的响应决定是使用缓存还是获取新的资源副本。
浏览器缓存对于提高网页加载速度和降低服务器负载非常重要。但有时候,如果服务器上的资源发生了更新,可能需要手动刷新缓存,以获取最新的资源。在开发过程中,可以通过设置响应头字段来控制缓存的行为,以便进行调试和测试。
3、DNS解析URL
- 请求发起后,游览器首先会解析这个域名,首先它会查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址。
- 本地DNS缓存查询:首先会检查本地DNS缓存中是否存在该域名的解析结果。如果存在,将直接返回对应的IP地址,查询结束。
- 递归查询:如果本地DNS缓存中没有域名的解析结果,本地DNS服务器将发起递归查询。它向根DNS服务器发送一个请求,询问根服务器所知道的顶级域名服务器(如.com、.net等)的地址。
- 根DNS服务器查询:根DNS服务器收到查询请求后,会根据顶级域名(如.com)提供本地顶级域名服务器的地址给本地DNS服务器。
- 顶级域名服务器查询:本地DNS服务器使用从根DNS服务器获得的顶级域名服务器地址,向顶级域名服务器发送查询请求。顶级域名服务器根据查询请求中的二级域名(如example.com)提供权威域名服务器的地址。
- 权威域名服务器查询:本地DNS服务器使用从顶级域名服务器获得的权威域名服务器地址,向权威域名服务器发送查询请求。权威域名服务器包含了所查询域名的DNS记录。
- DNS记录返回:权威域名服务器收到查询请求后,会查找并返回所需域名的DNS记录,包括IP地址或其他记录类型(如MX记录、CNAME记录等)。
- 结果返回给本地DNS服务器:权威域名服务器将查询结果返回给本地DNS服务器。
- 结果返回给用户:本地DNS服务器接收到查询结果后,将结果存储到本地DNS缓存中,并将查询结果返回给用户的设备。
- 用户访问目标网站:用户设备接收到DNS解析结果(IP地址),将使用该IP地址与目标网站建立连接,并发起访问请求。
4、建立TCP连接(三次握手)
TCP三次握手的过程如下:
- 第一次握手(SYN): 客户端(通常是浏览器)向服务器发送一个特殊的TCP报文段,其中设置了SYN(同步)标志位,并选择一个随机的初始序列号(ISN)作为初始通信序列号。这个报文段表示客户端请求建立连接。
- 第二次握手(SYN-ACK): 服务器接收到客户端的SYN报文段后,会发送一个响应报文段作为回应。该响应报文段中设置了SYN和ACK(确认)标志位,并将确认号(ACK)设置为客户端的初始序列号加一,同时服务器也选择了一个随机的初始序列号(ISN)。这个报文段表示服务器接受了客户端的请求,并告知客户端可以开始发送数据。
- 第三次握手(ACK): 客户端接收到服务器的SYN-ACK报文段后,会发送一个带有ACK标志位的报文段作为确认。客户端将确认号设置为服务器的初始序列号加一,同时将自己的序列号设置为初始序列号加一。这个报文段表示客户端接受了服务器的响应,并告知服务器可以开始发送数据
5、HTTP发起请求
浏览器构建一个HTTP请求消息,包括请求行、请求头和请求体。请求行包含请求方法(GET、POST、PUT等)和请求的URL。请求头包含关于请求的附加信息,例如Accept(指示浏览器可以接受的内容类型)、Cookies(存储在浏览器中的服务器相关数据)等。请求体(在某些请求中存在)包含要发送给服务器的数据,例如在POST请求
6、服务器处理请求,浏览器接收HTTP响应
响应报文主要包括以下几个方面:
- 状态行(Status Line):响应报文的第一行是状态行,用于指示服务器对请求的处理结果。状态行由三部分组成:HTTP协议版本号、状态码和状态消息。例如,一个常见的状态行可能是:HTTP/1.1 200 OK。其中,HTTP/1.1是协议版本号,200是状态码表示成功,OK是状态消息。
- 响应头(Response Headers):紧接着状态行后面是一系列的响应头。响应头提供了关于响应的附加信息,例如服务器类型、日期、内容类型等。每个响应头都由一个名称和一个值组成,中间用冒号分隔。例如,Content-Type: text/html表示响应的内容类型是HTML文档。 3 响应体(Response Body):空行之后是响应体,它包含了服务器返回给客户端的实际数据。响应体的内容格式取决于响应的内容类型。例如,如果内容类型是text/html,则响应体可能包含HTML标记的文本。
| 状态码分类 | 说明 |
|---|---|
| 1XX | 响应中--临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它 |
| 2XX | 成功--表示请求已经被成功接受,处理已完成 |
| 3XX | 重定向--重定向到其他地方(让客户端再发起一个请求以完成整个处理) |
| 4XX | 客户端错误--处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等 |
| 5XX | 服务器端错误--处理发生错误,责任在服务器端,如:服务端抛出异常,路由出错,HTTP版本不支持等 |
7、关闭TCP连接(四次挥手)
在TCP协议中,当通信双方完成数据交换或需要断开连接时,可以选择关闭TCP连接或继续保持连接。
- 关闭TCP连接:如果通信双方都完成了数据交换,并且不再需要保持连接,则可以通过四次握手的过程来关闭TCP连接。四次握手是指通过发送特定的TCP报文段来协商连接的关闭,确保双方都知道连接即将关闭。一旦完成四次握手,TCP连接就会被正式关闭,释放相关的资源。
- 继续保持连接:在某些情况下,通信双方可能需要保持连接的状态,以便在将来的时间内继续进行数据交换。这种情况下,双方可以选择不关闭TCP连接,而是保持连接处于活动状态。通过保持连接,可以减少建立新连接的开销,并在需要时立即进行通信。
选择关闭TCP连接还是继续保持连接取决于具体的应用场景和需求。在某些情况下,例如网页浏览,每个HTTP请求都可以使用独立的TCP连接,因此可以在每个请求之后关闭连接。而在其他情况下,例如实时通信应用程序,可能需要保持长时间的连接,以便实时传输数据。
四次挥手:
第一次挥手: Client端发起挥手请求,向Server端发送标志位是FIN报文段,设置序列号seq,此时,Client端进入FIN_WAIT_1状态,这表示Client端没有数据要发送给Server端了。
第二次挥手:Server端收到了Client端发送的FIN报文段,向Client端返回一个标志位是ACK的报文段,Server端告诉Client端,我收到了你的关闭请求。
第三次挥手: Server端向Client端发送标志位是FIN的报文段,请求关闭连接,同时Client端进入LAST_ACK状态。
第四次挥手 : Client端收到Server端发送的FIN报文段,向Server端发送标志位是ACK的报文段,然后Client端进入TIME_WAIT状态。Server端收到Client端的ACK报文段以后,就关闭连接。此时,Client端等待2MSL(最长报文段寿命)的时间后依然没有收到Server的重发FIN报文,则证明Server端已正常关闭,那好,Client端也可以关闭连接了。
8、渲染页面,构建DOM树
- 解析HTML:浏览器首先接收到HTML代码,并进行解析。解析过程将HTML代码转换为一个由多个节点组成的树状结构,即DOM树(Document Object Model)。解析器会逐个读取HTML标记和文本内容,并根据标记的嵌套关系构建DOM节点。
- 构建DOM树:解析器根据HTML标记的嵌套关系和文本内容构建DOM树。每个HTML元素都表示为DOM树中的一个节点,包括根节点(通常是
<html>元素)、父节点、子节点和兄弟节点等。 - 处理CSS:在构建DOM树的同时,浏览器还会处理CSS样式信息。浏览器会解析CSS样式表,并将样式规则应用于DOM节点,计算出每个节点的最终样式。这包括计算元素的尺寸、颜色、字体等属性。
- 构建渲染树:浏览器将DOM树和计算好的CSS样式信息组合成渲染树(Render Tree)。渲染树只包含需要显示的节点,并且每个节点都与其对应的样式信息关联。渲染树的构建过程中,一些不显示的元素(如
<head>、<script>等)会被省略。 - 布局(回流):渲染树构建完成后,浏览器进行布局(也称为回流)操作。布局过程确定每个渲染树节点在页面中的确切位置和大小。浏览器会计算每个元素在屏幕上的几何位置,并考虑到盒模型、浮动、定位等因素。
- 绘制(重绘):布局完成后,浏览器进入绘制(也称为重绘)阶段。在绘制过程中,浏览器根据渲染树的布局信息将页面元素绘制到屏幕上。这包括绘制元素的边框、背景、文本等。
- 显示:绘制完成后,浏览器会将绘制好的页面内容显示在用户的屏幕上。
浏览器的渲染过程,可以看这个:《浏览器的渲染过程》