在面试过程中常常会遇到这样一个问题:请你详细描述一下从我们在浏览器中输入网址到最后看到网页,这个过程中发生了什么?这个问题涉及面十分广,几乎涵盖了计网的全部相关问题,这个题的答案因人而异,可以挑选一两个着重点进行详细说明,其他的略过。
当我们将网址输入到浏览器后,第一件事就是解析 url 得到域名,通过 DNS 协议 获取到该域名的 ip 地址,得到 ip 后浏览器会先与服务器通过 TCP 三次握手建立连接,然后构建 HTTP 请求,将 HTTP 的传输工作交给操作系统的协议栈,发送请求成功后,浏览器会从服务端拿到该页面的 HTML 以及资源文件,浏览器会 渲染页面,呈现出我们所看到的模样。
在这整个过程中,涉及到了 DNS 解析,http请求,TCP\IP 协议栈、页面渲染等知识,当然也可以继续扩展,比如从 HTTP 可以说到 HTTPS,可以说到对称加密与非对称加密,可以说到网络安全等等,主要目的就是让整个面试过程跟着你的技术栈走,而不被面试官带到你不会的地方。
在这里我将重点写一下我在面试中喜欢拓展的方向,并拟出一份答案。
浏览器在拿到 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 地址了。
在解析 url 时,我们能获取到需要请求资源的资源路径、端口号、请求参数等信息,这些信息会被存储在 http 头中,通过 DNS 请求获取到ip后,浏览器会构建并发送 HTTP 请求或者 HTTPS 请求,HTTPS 就是在 HTTP 的基础上加了一个 TLS 协议来进行数据加密,这个我们待会说。
HTTP 请求有很多种,但对资源的操作离不开增删改查,也就对应着 POST、DELETE、PUT、GET 请求。最常用的是 GET 和 POST,其区别在于 GET 的参数是在 url 中的,而 POST 的参数是在请求的 body 中。
以 GET 为例,当需要发送 HTTP 请求的时候,同样也不是直接就发送了,需要先查询浏览器缓存。浏览器中的缓存分为强缓存和协商缓存,浏览器发起 HTTP 请求时首先会根据 http 头信息来判断是存有强缓存,以及其是否过期,如果有强缓存且未过期则命中,不会发送请求到服务器了。如果强缓存没命中,则会向服务器发起请求,这个请求的 Header 头中会带有浏览器最后一次请求该资源的时间和一个资源校验码(使用资源修改时间、资源大小等信息生成),服务器收到这个请求后会判断协商缓存是否过期,如果过期则返回新的资源信息,如果没过期则返回 304 状态码,表示资源未更新,可以使用缓存中的资源。
TCP 这一块内容比较多,所以一般不会在这个问题中详细说明,这里只写一个过渡段,想要了解 TCP 相关问题解答的可以看我的另一篇博客:TCP详解
HTTP 请求发出后会将数据包交给下层协议栈处理,在传输层和网络层该数据包会被分别加上 TCP 头和 IP 头,并且被发送出去,沿路的网关会收到这个数据包并进行识别和转发,直到该数据包被服务器收到,通过相同的流程返回回复数据包。
由于我对前端不熟悉,就不展开讲,被问到的话就说是通过写爬虫来了解DOM树的(挪威组),前端只会简单的 Vue 开发,底层原理不了解
一般来说,浏览器第一次从服务器请求的资源都是一个 HTML 文件,例如服务端默认的 index.html 等,浏览器获取到这个 HTML 文件就会对其进行解析,构建出一棵 DOM 树,并通过执行其中的 js 代码发起更多的请求,请求渲染页面需要的其他资源,CSS 或者一些外链的图片等,拿到 CSS 后将其与 DOM 树结合进行更进一步的渲染,我们就能看到页面了。
由于 HTTP 是使用信息明文传播,所以会有窃听、篡改、冒充等风险,所以 HTTPS 在 HTTP 的基础上加上了 SSL 层,通过加密的方式来保证数据安全。
SSL 通过加密防止窃听,通过签名来防止篡改,通过证书来防止冒充。
HTTPS 协议在客户端与服务端开始通信前,会进行密钥协商,通过一轮非对称加密,一般是RSA加密来传递后序通信过程使用的对称密钥,由于非对称加密较慢,后续通信过程中使用对称加密。在密钥协商的过程中,服务端会将自己的证书发送给客户端,客户端会到CA机构通过摘要值验证证书的合法性,从而防止中间人攻击。
中间人攻击主要分为 SSL 劫持攻击、SSL 剥离攻击以及针对 SSL 算法的攻击
浏览器在拿到 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 地址了。
得到 ip 后浏览器会先与服务器通过 TCP 三次握手建立连接,然后构建 HTTP 请求。
在解析 url 时,我们能获取到需要请求资源的资源路径、端口号、请求参数等信息,这些信息会被存储在 http 头中,通过 DNS 请求获取到 ip 后,浏览器会构建并发送 HTTP 请求或者 HTTPS 请求,HTTPS 就是在 HTTP 的基础上加了一个 TLS 协议来进行数据加密,这个我们待会说。
HTTP 请求有很多种,但对资源的操作离不开增删改查,也就对应着 POST、DELETE、PUT、GET 请求。最常用的是 GET 和 POST,其区别在于 GET 的参数是在 url 中的,而 POST 的参数是在请求的 body 中。
以 GET 为例,当需要发送 HTTP 请求的时候,同样也不是直接就发送了,需要先查询浏览器缓存。浏览器中的缓存分为强缓存和协商缓存,浏览器发起 HTTP 请求时首先会根据 http 头信息来判断是存有强缓存,以及其是否过期,如果有强缓存且未过期则命中,不会发送请求到服务器了。如果强缓存没命中,则会向服务器发起请求,这个请求的 Header 头中会带有浏览器最后一次请求该资源的时间和一个资源校验码(使用资源修改时间、资源大小等信息生成),服务器收到这个请求后会判断协商缓存是否过期,如果过期则返回新的资源信息,如果没过期则返回 304 状态码,表示资源未更新,可以使用缓存中的资源。
HTTP 请求发出后会将数据包交给下层协议栈处理,在传输层和网络层该数据包会被分别加上 TCP 头和 IP 头,并且被发送出去,沿路的网关会收到这个数据包并进行识别和转发,直到该数据包被服务器收到,通过相同的流程返回回复数据包。
一般来说,浏览器第一次从服务器请求的资源都是一个 HTML 文件,例如服务端默认的 index.html 等,浏览器获取到这个 HTML 文件就会对其进行解析,构建出一棵DOM树,并通过执行其中的 js 代码发起更多的请求,请求渲染页面需要的其他资源,CSS 或者一些外链的图片等,拿到 CSS 后将其与 DOM 树结合进行更进一步的渲染,我们就能看到页面了。
最后再补充一下 HTTPS,由于 HTTP 是使用信息明文传播,所以会有窃听、篡改、冒充等风险,所以 HTTPS 在 HTTP 的基础上加上了 SSL 层,通过加密的方式来保证数据安全。
SSL 通过加密防止窃听,通过签名来防止篡改,通过证书来防止冒充。
HTTPS 协议在客户端与服务端开始通信前,会进行密钥协商,通过一轮非对称加密,一般是RSA加密来传递后序通信过程使用的对称密钥,由于非对称加密较慢,后续通信过程中使用对称加密。在密钥协商的过程中,服务端会将自己的证书发送给客户端,客户端会到 CA 机构通过摘要值验证证书的合法性,从而防止中间人攻击。