浏览器输入www.baidu.com之后,发生了什么?

1、将域名www.baidu.com解析为IP地址:

解析IP地址的过程依次经过了:浏览器缓存、系统缓存、hosts文件、路由器缓存、递归搜索根域名服务器。

  • 浏览器缓存: 每个浏览器都会有一个DNS缓存,记录了一些常用域名和IP地址的对应关系(有过期时间),当在浏览器的DNS缓存中没有找到对应关系时,会查询系统缓存。

  • 系统缓存: 浏览器会进行一个系统调用(Windows里面是gethostbyname),检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名的映射。有,直接返回对应的IP地址;没有的话就去查询路由器缓存。

  • 路由器缓存: 查询路由器的DNS缓存,没有就去查本地DNS服务器。

  • 递归搜索DNS服务器:

浏览器输入www.baidu.com之后,发生了什么?_第1张图片

  1. 系统会把浏览器的解析请求发送到本地DNS服务器,如果缓存中有对应的解析记录,就会直接返回IP地址;没有的话本地 DNS 服务器还要向 DNS 根服务器进行查询。

  2. 本地 DNS 服务器向根服务器发送 DNS 请求,如果根服务器经过查询,没有记录该域名及 IP 地址的对应关系,就会告诉本地 DNS 服务器,可以到域名服务器上继续查询,并给出域名服务器的地址(.com 服务器)。

  3. 本地 DNS 服务器向 .com 服务器发送 DNS 请求,.com 服务器收到请求后,不会直接返回域名和 IP 地址的对应关系,而是告诉本地 DNS 服务器,该域名可以在 baidu.com 域名服务器上进行解析获取 IP 地址,并告诉 baidu.com 域名服务器的地址。

  4. 本地 DNS 服务器向 baidu.com 域名服务器发送 DNS 请求,baidu.com 服务器收到请求后,在自己的缓存表中发现了该域名和 IP 地址的对应关系,并将IP地址返回给本地 DNS 服务器。

  5. 本地 DNS 服务器将获取到与域名对应的 IP 地址返回给客户端,并且将域名和 IP 地址的对应关系保存在缓存中,以备下次别的用户查询时使用。
    浏览器输入www.baidu.com之后,发生了什么?_第2张图片


2、建立TCP/IP连接(三次握手)

浏览器输入www.baidu.com之后,发生了什么?_第3张图片

假设 A 为客户端,B 为服务器端:

  • 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。

  • A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x。

  • B 收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。

  • A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。

  • B 收到 A 的确认后,连接建立。

  • 三次握手的原因

    ​ 第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。

3、浏览器根据解析得到的IP地址向 web 服务器发送一个 HTTP 请求

​ 像baidu主页这样的动态页面,打开后在浏览器缓存中很快甚至马上就会过期,毫无疑问他们不能从中读取。所以,浏览器将把一下请求发送到baidu所在的服务器:

GET https://www.baidu.com/ HTTPS/1.1   
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36      // User-Agent:发送请求的应用程序名称
Accept-Encoding: gzip, deflate, br     //指定可接收的数据压缩格式
Accept-Language: zh-CN,zh;q=0.9       //指定可以接收的语言
Connection: keep-alive
Host: www.baidu.com                 //接收请求的服务器地址,可以是ip也可以是端口号
Cookie: datr=1265876274-[...]; locale=en_US; lsd=WW[...]; c_user=2101[...]

​ GET 这个请求定义了要读取的URL: “https://baidu.com/”。 浏览器自身定义 (User-Agent 头), 和它希望接受什么类型的相应 (Accept and Accept-Encoding 头)。 Connection头要求服务器为了后边的请求不要关闭TCP连接。

​ 请求中也包含浏览器存储的该域名的cookies。可能你已经知道,在不同页面请求当中,cookies是与跟踪一个网站状态相匹配的键值。这样cookies会存储登录用户名,服务器分配的密码和一些用户设置等。Cookies会以文本文档形式存储在客户机里,每次请求时发送给服务器。

​ 用来看原始HTTP请求及其相应的工具很多,例如:fiddler、FireBug等工具,这些软件在网站优化时会帮上很大忙。除了获取请求,还有一种是发送请求,它常在提交表单用到。发送请求通过URL传递其参数(e.g.: http://robozzle.com/puzzle.aspx?id=85),发送请求在请求正文头之后发送其参数。

​ 像“https://baidu.com/”中的斜杠是至关重要的。这种情况下,浏览器能安全的添加斜杠。而像“http: //example.com/folderOrFile”这样的地址,因为浏览器不清楚folderOrFile到底是文件夹还是文件,所以不能自动添加 斜杠。这时,浏览器就不加斜杠直接访问地址,服务器会响应一个重定向,结果造成一次不必要的握手。

4、经路由器转发,将HTTP请求送达服务器

​ 首先在应用层,根据当前的需求和动作,结合应用层的协议和确定发送的数据内容,我们把这些数据放到一个缓冲区内,然后形成了应用层的报文data

​ 这些数据通过传输层发送(HTTP请求采用tcp协议),在这里报文打上了传输头的报头,主要包含端口号,以及tcp的各种制信息,这些信息是直接得到的,因为接口中需要指定端口,这样就组成了tcp的数据传送单位segment

​ 然后待发送的数据段送到网络层,在网络层被打包,这样封装上了网络层的报头,报头内部含有源及目的的ip地址,该层数据发送单位被称为packet。网络层开始负责将这样的数据包在网络上传输,如何穿过路由器,最终到达目的地址。在这里,根据目的ip地址,就需要查找下一跳路由的地址。首先在本机,要查找本机的路由表,在windows上运行route print就可以看到当前路由表内容,有如下几项:

  • Active Routes
  • Default Route
  • Persistent Route

整个查找过程如下:

(1)根据目的地址,得到目的网络号,如果处在同一个内网,则可以直接发送。

(2)如果不是,则查询路由表,找到一个路由。

(3)如果找不到明确的路由,此时在路由表中还会有默认网关,也可称为缺省网关,IP用缺省的网关地址将一个数据传送给下一个指定的路由器,所以网关也可能是路由器,也可能只是内网向特定路由器传输数据的网关。

(4)路由器收到数据后,它再次为远程主机或网络查询路由,若还未找到路由,该数据包将发送到该路由器的缺省网关地址。而数据包中包含一个最大路由跳数,如果超过这个跳数,就会丢弃数据包,这样可以防止无限传递。路由器收到数据包后,只会查看网络层的包裹数据,目的ip。所以说它是工作在网络层,传输层的数据对它来说则是透明的。

如果上面这些步骤都没有成功,那么该数据报就不能被传送。如果不能传送的数据报来自本机,那么一般会向生成数据报的应用程序返回一个“主机不可达”或 “网络不可达”的错误。

5、服务器处理HTTP请求,并返回HTML文件

  • 接收http请求

    web服务器链接表中有许多链接需求要被处理,处理的方式包括单线程和多线程等,一旦web服务器端接收到某条链路的请求就会将其加入相应的等待请求队列,等候处理。

  • 处理http请求

    将http请求的信息解析出来的大致过程如下:
    浏览器输入www.baidu.com之后,发生了什么?_第4张图片

  • 访问资源
    浏览器输入www.baidu.com之后,发生了什么?_第5张图片

  1. 如果访问的资源是静态资源,则直接根据url地址去服务器里面找;

  2. 如果访问动态资源的话,则需要先经过cgi,再用服务器脚本处理,最后返回给前端。

  • 构建响应

    找到资源:构建响应信息,包括响应的对象类型、长度、状态码等。

    未找到资源:构建重定向响应,直接返回重定向,客户端收到响应后再向重定向地址发送请求,重定向的响应状态码一般是3**。

6、浏览器解析HTML文件,并显示

浏览器是按顺序解析html文档的,但是浏览器解析html文档的第一步,是并行发出请求来请求所有的外部资源。然后再从头开始解析,如果有js等外部资源还没有加载则需要等待。

浏览器解析HTML的流程:

  1. 解析HTML结构
  2. 并行加载脚本、样式表文件、img等外部资源
  3. 如有js文件未下载,则等待下载完成(js文件前如有css文件,则需要先等css文件下载完成)
  4. 脚本下载后立即执行,然后从当前解析处开始解析
  5. DOM树构建完成。//DOMContentLoaded
  6. 解析外部css文件,img图片等资源
  7. paint,渲染页面
  8. 页面加载完毕。//load

浏览器输入www.baidu.com之后,发生了什么?_第6张图片

开始从头到尾解析HTML,并生成DOM树。其中如果有外链资源,需要再次通过网络层以此下载。如果是"script"标签,则需要调用JS引擎执行脚本;如果是css,则开始解析CSS,得到一系列样式规则;DOM树生成之后,与样式规则拼接,得到渲染树。渲染树经过排版引擎得到最终的渲染位置和样式,然后调用操作系统的绘图API绘制页面(部分内容会调用显卡进行硬件加速)。

扩展

  1. 浏览器在拿到 url 时,首先会对 url 进行解析,将域名与实际的文件路径分离,然后需要使用 DNS 协议,通过域名得到 IP 地址。
  • 浏览器会查询浏览器缓存,如果有这个网址的缓存就可以直接获取到 IP,如果没有就进一步访问本机缓存,如果本机缓存也没有才会发起 DNS 请求。

  • 而 DNS 的服务器是一个树状结构,对于域名来说是倒着进行解析的,根节点是根 DNS 服务器,他的子节点为 com、cn 这种顶级域 dns 服务器,然后进一步向下进行解析。

  • 以 baidu.com 为例,当我们的电脑需要发起 DNS 请求的时候,会先对根 DNS 服务器发起请求,这个服务器的 IP 地址一般在每台电脑上都有,我们一般会设置为 8.8.8.8 或者 114.114.114.114,我们的电脑在访问根 DNS 服务器后,会得到 con 域 DNS 服务器的 IP,然后会继续访问 con 域 DNS 服务器,这时就能得到 baicu.com 的 IP 地址了。

  1. 得到 ip 地址后,浏览器会先与服务器通过 TCP 三次握手建立连接,然后构建 HTTP 请求。

    注意:

    • HTTP协议是一种基于TCP/IP的应用层协议,进行HTTP数据请求必须先建立TCP/IP连接

    • 可以这样理解:

      1. HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
      2. 两个计算机之间的交流无非是两个端口之间的数据通信,具体的数据会以什么样的形式展现是以不同的应用层协议来定义的。
  2. 通过 DNS 请求获取到 ip 后,浏览器会构建并发送 HTTP 请求或者 HTTPS 请求,HTTPS 就是在 HTTP 的基础上加了一个 TLS 协议来进行数据加密。HTTP 请求发出后会将数据包交给下层协议栈处理,在传输层和网络层该数据包会被分别加上 TCP 头和 IP 头,并且被发送出去,沿路的网关会收到这个数据包并进行识别和转发,直到该数据包被服务器收到,通过相同的流程返回回复数据包。

HTTP 请求有很多种,但对资源的操作离不开增删改查,也就对应着 POST、DELETE、PUT、GET 请求。最常用的是 GET 和 POST,其区别在于 GET 的参数是在 url 中的,而 POST 的参数是在请求的 body 中。

以 GET 为例,当需要发送 HTTP 请求的时候,同样也不是直接就发送了,需要先查询浏览器缓存。

浏览器中的缓存分为强缓存和协商缓存,浏览器发起 HTTP 请求时首先会根据 http 头信息来判断是存有强缓存,以及其是否过期,如果有强缓存且未过期则命中,不会发送请求到服务器了。

如果强缓存没命中,则会向服务器发起请求,这个请求的 Header 头中会带有浏览器最后一次请求该资源的时间和一个资源校验码(使用资源修改时间、资源大小等信息生成),服务器收到这个请求后会判断协商缓存是否过期,如果过期则返回新的资源信息,如果没过期则返回 304 状态码,表示资源未更新,可以使用缓存中的资源。

  1. 服务端在解析 url 时,我们能获取到需要请求资源的资源路径、端口号、请求参数等信息,这些信息会被存储在 http 头中。服务端通过解析http请求中的相关信息,访问相应的资源(静态资源或动态资源),并生成相应的HTML文件发送给浏览器。

一般来说,浏览器第一次从服务器请求的资源都是一个 HTML 文件,例如服务端默认的 index.html 等,浏览器获取到这个 HTML 文件就会对其进行解析,构建出一棵DOM树,并通过执行其中的 js 代码发起更多的请求,请求渲染页面需要的其他资源,CSS 或者一些外链的图片等,拿到 CSS 后将其与 DOM 树结合进行更进一步的渲染,我们就能看到页面了。

  1. 补充:
    • HTTPS,由于 HTTP 是使用信息明文传播,所以会有窃听、篡改、冒充等风险,所以 HTTPS 在 HTTP 的基础上加上了 SSL 层,通过加密的方式来保证数据安全。
    • SSL 通过加密防止窃听,通过签名来防止篡改,通过证书来防止冒充。
    • HTTPS 协议在客户端与服务端开始通信前,会进行密钥协商,通过一轮非对称加密,一般是RSA加密来传递后序通信过程使用的对称密钥,由于非对称加密较慢,后续通信过程中使用对称加密。在密钥协商的过程中,服务端会将自己的证书发送给客户端,客户端会到 CA 机构通过摘要值验证证书的合法性,从而防止中间人攻击。

你可能感兴趣的:(计算机网络,计算机网络)