![640?wx_fmt=jpeg](https://i-blog.csdnimg.cn/blog_migrate/3752c8576f46063a3262e0d1d7e2e2c0.jpeg)
“在浏览器地址栏中输入 google.com,然后按下回车键,之后会发生些什么?”
这是我最喜欢的面试题之一。有人可以连续说上几天,试图完整地回答这个问题。我也想说说我的答案。当我在一个面试中被问到这个问题时,我滔滔不绝地讲了 10 分钟,直到面试官打断了我。然后,即使是在面试结束之后,我还在想有些东西还没有讲完。
那么究竟会发生些什么?
首先,浏览器将会分析你输入的内容。通常,如果输入的内容里包含了“.com”,浏览器不会认为你输入的是一个搜索关键字。在确定它是一个 URL 之后,浏览器会检查它是否指明了某种协议,如果没有,就会在开头添加“http://”。因为你没有指定具体的 HTTP 协议选项,所以浏览器会使用默认值,如端口 80、GET 方法、不使用基本的身份验证。
然后它会创建一个 HTTP 请求并将请求发送出去。我对底层的网络知识不是很了解,否则我会说一些有关 MAC 地址、TCP 数据包传输、如何处理数据包丢失的东西。但不管怎样,它肯定会先进行 DNS 查找,如果在缓存中找不到,DNS 服务会返回一个 IP 地址列表,因为“google.com”不只对应一个 IP 地址。浏览器会默认选择第一个。我不确定它们是否具有区域性,也不知道究竟是如何使用 IP 地址列表的,我只知道有这么一串 IP 地址存在。
HTTP 请求从一个节点跳到另一个节点,直到到达 google.com 负载均衡器的 IP 地址。这不会持续很长时间,谷歌会告诉你需要使用 HTTPS——假设它会使用 301 状态码来告诉你需要进行重定向。这个状态码被发送回你的浏览器,浏览器将协议改为 HTTPS,使用默认的 443 端口,并重新发送请求。这次,在负载均衡器和浏览器之间会发生 TLS 握手。我不是百分之百清楚握手过程是怎么回事,但我知道请求会告诉 Google 它支持哪些协议(TLS 1.0,1.1,1.2),Google 会回答“那就让我们使用 1.2 吧”,然后就通过 TLS 加密发送请求。
我认为 Google 要做的下一件事是通过负载均衡器上的 Web 应用程序防火墙规则来检查它是否是恶意请求。在通过检查后,安全连接可能就终止了(因为 PCI-DSS 安全标准规定不需要加密内部流量),请求将被分配到 CDN 池中,然后通过 HTTP 响应返回 Google 主页,可能是预先压缩过的。
浏览器将读取返回的消息响应头,根据响应头的缓存策略对内容进行缓存,然后正文将被解压缩。Google 可能对消息做过优化,比如对正文进行了缩小化,包括很多预渲染内容、内联 CSS、JavaScript 和图像,以便减少网络请求数和首次渲染时间。然后这个请求将触发一系列其他请求,所有这些请求都是并发的,因为使用了 HTTP/2。在发出这些请求的同时,JavaScript 会被解析,可能会使用非阻塞模式,因为标签上使用了 defer 或 async。
此时,浏览器可能已经渲染好了搜索框,并对顶部的工具栏做一些事情,这需要一些额外的网络请求——我可能已经有 Cookie 了,或者是带有 OAuth 令牌的本地存储——或我使用的是 Chrome,所以它已经知道我是谁,然后将请求和认证信息发送给 Google+ API,告诉 Google 搜索应用程序我是谁。
另一个请求将被发送给服务器,用来获取我的头像。这个时候,他们可以嗅探我是不是在使用 Chrome,如果不是,他们会弹出一个工具提示框,告诉我 Chrome 有多好,我应该使用它而不是其他浏览器。
我认为差不多就是这样,一切都发生在一眨眼的功夫内。
有哪些明显不一样的地方?
让我们来看看 DNS 查找:
我以前见过 google.com 会返回多个 IP 地址,但现在可能不再是这种情况了。他们以前似乎使用了 round-robin,但现在不再使用这种方式了。StackOverflow 上有个问题对此进行了解答(https://stackoverflow.com/questions/10257969/is-it-possible-that-one-domain-name-has-multiple-corresponding-ip-addresses)。
网络层
在正式回答这个问题时,你可能会提到 OSI 模型,虽然我也知道这个模型,但并不精通。经过一番研究之后,我发现网络层是这样的:
应用层——发起请求的逻辑
表示层——HTTP
会话层——TLS
传输层——TCP
网络层——数据包路由(IP)
数据链路层——帧(就像是数据包的容器)
物理层——比特流
在进行 TLS 握手时,在确定协议之后它们会交换证书,这点被我漏掉了。网络方面的知识不是我的强项。
在浏览器中打开 google.com,并禁用缓存:
我漏掉了主机名规范化——是一个 301 状态码。
从 HTTP 到 HTTPS 的纠正是一个 307 内部重定向。
然后它下载字体、logo 图像和我的头像。没有 API 调用,说明他们在页面中推送我的个人信息,并将其与响应消息捆绑在一起。
响应消息
以上是 IE 11 和 Chrome 响应消息的比较。
IE11 和 Chrome 之间没有太大的不同。这说明他们是在服务器端而不是客户端进行 user-agent 嗅探,我可以在回答问题时提到这一点。
出乎意料的是,Chrome 的响应消息大了 22KB。我在想是不是因为语音搜索功能导致的,因为在 IE 11 中没有这项功能。IE11 可能需要 polyfill 并进行 Chrome 推广,但这有点扯远了,我也不想再进一步折磨自己了。
即使我在 Chrome 中清除了 Cookie,它仍会在第一次请求时发送 Cookie,但在 IE 11 中不会这样。
让我们来了解一下渲染机制!
上面是 Chrome 为你渲染的第一个页面。
script 标签上没有使用 async 或 defer 属性,只有 nonce 属性。我正在了解 nonce,它似乎与安全有关。我猜他们想要使用这些阻塞脚本。我敢确定他们在某个时候对 async 和 defer 进行过 fiddle 分析,最后决定不使用这两个属性。
需要注意的是:完整的响应消息包含了一堆乱七八糟的 JavaScript、CSS 和 HTML 混合代码。他们没有遵循任何代码拆分规则。
现在回到这个问题本身
对于开发人员而言,这可能不是一个很好的面试问题,因为答案涉及到太多网络知识。但这是我喜欢的问题类型,因为是开放性的,还包含了一些猜测的成分。面试官因此就有机会问候选人“你认为 TLS 是如何建立的”之类的问题,看看候选人如何思考,看看他们的创意能力,看看他们的极限是什么(比如是不是有耐心)。
那么,你最喜欢的面试问题是什么?
扩展阅读
来源:聊聊架构
英文原文:https://dev.to/antonfrattaroli/what-happens-when-you-type-googlecom-into-a-browser-and-press-enter-39g8
文章来源网络,版权归作者本人所有,如侵犯到原作者权益,请与我们联系删除