输入网址后浏览器干了什么?

143 阅读11分钟

干什么了的流程清单

  1. URL的解析
  2. DNS的查询
  3. 与服务器进行TCP的连接
  4. 发送 HTTP / HTTPS 请求
  5. 处理服务器的响应请求
  6. 浏览器渲染页面

URL的解析

我们在浏览器输入URL后,浏览器会对你输入的内容进行判断和检查

  • 检查输入的内容是否是一个合法的 URL 链接
  • **如果是,**则判断输入的 URL 是否完整。如果不完整,浏览器可能会对域进行猜测,补全前缀或者后缀
  • 如果不是,将输入内容作为搜索条件,使用用户设置的默认搜索引擎来进行搜索,要是搜索内容的话结合搜索引擎转化为url

大部分浏览器会从历史记录、书签等地方开始查找我们输入的网址,并给出智能提示

URL(统一资源定位符,Uniform Resource Locator)用于定位互联网上资源,俗称网址。

DNS查询

ip地址是服务器的身份证,所以我们请求的本质就是通过服务器的ip地址请求服务器,但是ip太过难记,所以就需要DNS服务器,类似于地址表,记录着ip与域名的对应关系,域名相当于人的名字

下面是浏览器由域名得到ip地址的过程

检查浏览器缓存

操作系统会先检查浏览器缓存,如果有这网址的记录则DNS解析结束

检查本地hosts文件

操作系统会检查自己本地的hosts文件,如果有网址记录则DNS解析结束

检查本地 DNS 解析器缓存

操作系统会本地 DNS 解析器缓存,如果有网址记录则DNS解析结束

当您在浏览器中输入一个网址时,浏览器内部的DNS解析器会将这个域名发送到DNS服务器以获取与之对应的IP地址

检查路由器缓存

对路由器的缓存进行检查,如果有网址记录则DNS解析结束、

检查本地 DNS 服务器

操作系统会检查本地 DNS 服务器,如果有网址记录则DNS解析结束

主机到本地 DNS 服务器的查询是递归查询!!!

如果都没有该网址的记录,则接下来则会向根域名服务器等一系列进行请求信息

以下查询过程的操作都是迭代查询!!!

在网络中寻找域名ip

我们先说一下DNS服务器的分类

DNS服务器分类

大致可以分为以下三种

  • DNS 根域名服务器
  • TLD 域名服务器(顶级域 DNS 服务器)
  • 权威性域名服务器
  • 本地域名服务器(不算是分类,由客户指定)

每个服务器的具体作用可以来DNS 服务器类型 | Cloudflare了解

TLD 域名服务器维护共享通用域扩展名的所有域名的信息,例如 .com、.net 或 url 中最后一个点之后的任何内容。例如,.com TLD 域名服务器包含以“.com”结尾的每个网站的信息。

步骤

  1. 首先本地的DNS服务器会向根DNS服务器发送查询请求,然后DNS根服务器会返回相应的顶级域名服务器的ip(比如你请求的网址是www.baidu.com那么顶级域名服务器就会返回.com的顶级域名服务器的ip)
  2. 本地服务器收到顶级域名服务器的ip后,向顶级域名服务器发送查询请求,顶级域名服务器会返回其网址的权威域名服务器的ip(权威域名服务器会包含特定的域名信息,这也是为什么需要ip的原因,这个网址的信息不是所有的DNS服务器都会有)
  3. 本地DNS服务器在收到权威域名服务器的ip后,会向权威域名服务器发起请求,然后权威域名服务器就会返回网址的ip

至此,DNS服务器获取ip结束

但是还有以下三部才能给到浏览器

  • 本地域名服务器将得到的 ip 地址返回给操作系统,同时自己将 ip 地址缓存起来
  • 操作系统将ip地址返回给浏览器,同时自己也将 ip 地址缓存起
  • 至此,浏览器就得到了域名对应的ip地址,并将ip地址缓存起

与服务器建立TCP连接

世界上几乎所有的 HTTP 通信都是由 TCP/IP 承载的,TCP/IP 是全球计算机及网络设备都在使用的一种常用的分组交换网络分层。 HTTP 的连接实际上就是 TCP 连接以及其使用规则。 –《HTTP 权威指南》

首先,判断是不是https的,如果是,则HTTPS其实是HTTP + SSL / TLS 两部分组成,也就是在HTTP上又加了一层处理加密信息的模块,服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据

进行三次握手

第一次

首先客户端向服务器发送一个 SYN 包,并等待服务器确认,其中:

  • 标志位为 SYN,表示请求建立连接;
  • 序号为 Seq = x(x 一般取随机数);
  • 随后客户端进入 SYN-SENT 阶段。

第二次

服务器接收到客户端发来的 SYN 包后,对该包进行确认后结束 LISTEN 阶段,并返回一段 TCP 报文,其中:

  • 标志位为 SYN 和 ACK,表示确认客户端的报文 Seq 序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接;
  • 序号为 Seq = y;
  • 确认号为 Ack = x + 1,表示收到客户端的序号 Seq 并将其值加 1 作为自己确认号 Ack 的值,随后服务器端进入 SYN-RECV 阶段。

第三次

客户端接收到发送的 SYN + ACK 包后,明确了从客户端到服务器的数据传输是正常的,从而结束 SYN-SENT 阶段。并返回最后一段报文。其中:

  • 标志位为 ACK,表示确认收到服务器端同意连接的信号;
  • 序号为 Seq = x + 1,表示收到服务器端的确认号 Ack,并将其值作为自己的序号值;
  • 确认号为 Ack= y + 1,表示收到服务器端序号 seq,并将其值加 1 作为自己的确认号 Ack 的值。
  • 随后客户端进入 ESTABLISHED

当服务器端收到来自客户端确认收到服务器数据的报文后,得知从服务器到客户端的数据传输是正常的,从而结束 SYN-RECV 阶段,进入 ESTABLISHED 阶段,从而完成三次握手

发送 HTTP / HTTPS 请求

我们在建立了TCP连接后,我们就可以使用HTTP进行数据传输了,但是现在为了防止遭受中间人攻击更多的是会使用HTTPS进行数据的传输,会在 TCP 与 HTTP 之间多添加一层协议做加密及认证的服务,HTTPS 使用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security)协议,这里还涉及到一个TLS握手的过程

处理服务器的响应请求

HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是:

  • 状态行
  • 响应头(Response Header)
  • 响应正文

状态行

状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔

格式: HTTP-Version Status-Code Reason-Phrase CRLF例如: HTTP/1.1 200 OK

协议版本: 是用http1.0还是其他版本

状态描述: 状态描述给出了关于状态代码的简短的文字描述。比如状态代码为200时的描述为 ok

状态码:

状态码是由 3 位数组成,第一个数字定义了响应的类别,且有五类可能取值

  • 1xx:指示信息——表示请求已接收,继续处理

    • 100 Continue
    • 101 Switching Protocols
  • 2xx:成功——表示请求已被成功接收、理解、接受

    • 200 OK 表示客户端请求成功
    • 204 No Content 成功,但不返回任何实体的主体部分
    • 206 Partial Content 成功执行了一个范围(Range)请求
  • 3xx:重定向——要完成请求必须进行更进一步的操作

    • 301 Moved Permanently 永久性重定向,响应报文的Location首部应该有该资源的新URL
    • 302 Found 临时性重定向,响应报文的Location首部给出的URL用来临时定位资源
    • 303 See Other 请求的资源存在着另一个URI,客户端应使用GET方法定向获取请求的资源
    • 304 Not Modified 服务器内容没有更新,可以直接读取浏览器缓存
    • 307 Temporary Redirect 临时重定向。与302 Found含义一样。302禁止POST变换为GET,但实际使用时并不一定,307则更多浏览器可能会遵循这一标准,但也依赖于浏览器具体实现
  • 4xx:客户端错误——请求有语法错误或请求无法实现

    • 400 Bad Request 表示客户端请求有语法错误,不能被服务器所理解
    • 401 Unauthonzed 表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用
    • 403 Forbidden 表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因
    • 404 Not Found 请求的资源不存在,例如,输入了错误的URL
  • 5xx:服务器端错误——服务器未能实现合法的请求

    • 500 Internel Server Error 表示服务器发生不可预期的错误,导致无法完成客户端的请求
    • 503 Service Unavailable 表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常

响应头

这是一些常见的响应头

  • Cache-Control:must-revalidate、no-cache、private(是否需要缓存资源)
  • Connection:keep-alive(保持连接)
  • Content-Encoding:gzip(web 服务器支持的返回内容压缩编码类型)
  • Content-Type:text/html;charset=UTF-8(文件类型和字符编码格式)
  • Date:Sun, 21 Sep 2021 06:18:21 GMT(服务器消息发出的时间)
  • Transfer-Encoding:chunked(服务器发送的资源的方式是分块发送)

响应正文

包含着一些浏览器需要的信息,cookie html json 或者是其他数据来着的

浏览器渲染页面

浏览器在收到服务器发送的html文件后,会开始根据文件渲染页面,最后以像素输出到页面上

Critical Rendering Path

Critical Rendering Path,中文翻译过来,叫做关键渲染路径。指的是浏览器从请求 HTML,CSS,JavaScript 文件开始,到将它们最终以像素输出到屏幕上这一过程。

其关键的过程是:

  • 构建 DOM

    1. 将 HTML 解析成许多 Tokens
    2. 将 Tokens 解析成 Objects
    3. 将 Objects 组合成为一个 DOM 树
  • 构建 CSSOM

    解析 CSS 文件,并构建出一个 CSSOM 树(过程类似于 DOM 构建)

  • 构建 Render

    结合 DOM 和 CSSOM 构建出一颗 Render 树

  • 布局Layout

    计算出元素相对于 viewport(可见页面的区域) 的相对位置

  • Paint

    将 Render 树转换成像素,显示在屏幕上

上面的过程并不是依次进行的,而是存在一定交叉

断开TCP连接

四次挥手

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

  • 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  • 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

如下图解

为什么交手只需要是三次,而挥手需要四次呢?

交手,是双端从关闭状态转向开启状态,这时候双端并不需要做什么准备。 而相反,结束的时候,双端都需要确认对方的数据已经全部传送完毕了,才能结束。 所以把释放连接的报文FIN和确认接收的报文ACK,分开发送

小结

至此浏览器从输入网址到渲染页面的全部过程已经说完了,有一些步骤的详细过程并没有细说,只是大概描述其过程,有什么不懂的请各位指教,再见!!!