从浏览器网址列输入网址、按下 Enter 后会发生什么事?
2024年7月22日
如果有面试过软体工程师的工作,不论前端或后端,「从浏览器网址列输入网址、按下 Enter 后会发生什么事?」都是非常高频率会出现的题目。
这个题目之所以如此高频,是因为这问题会触及到网页开发、网络技术相关的重要概念。而因为题目很广,能够切入的角度非常多,所以让这个题目变得非常灵活,可广可深。如果没有对概念融会贯通、只是背答案,很可能在追问的问题后就答不出来。
E+(ExplainThis 所办的的订阅计划) 很高兴在 7/20 有小赖与我们分享「从浏览器网址列输入网址、按下 Enter 后会发生什么事?」这个面试常见的题目。
从宏观的角度看
如果从宏观的角度看,当从浏览器网址列输入网址、按下 Enter 后,浏览器会先透过 DNS (域名系统) 查找 IP,然后对在该 IP 位置的伺服器发送 HTTP 请求,然后伺服器会回应,最后浏览器把收到的回应渲染到画面上。
DNS
这时就有几个问题可以讨论,第一个是 DNS,你可能会问为什么需要有 DNS 的存在? 关于这问题,是因为我们输入的通常是网址的域名,但是实际上是要到某个 IP 位置,所以需要有域名对应到 IP 的表,而实际上就是透过 DNS 来维持的表,来对应域名与 IP。
举例来说:
- momoshop.com.tw 对应的 IP 是 61.219.4.15
- static.azoleonline.click 对应的 IP 是 54.71.13.152
这时又有另一个问题,世界上有成千上亿的 IP,输入网址后,如何快速查找到对应的 IP?
DNS 的做法是分组,每一个组会进一步拆解。一开始会先问 DNS Resolver,这时会先去问根伺服器 (Root),问完后会去问顶级域名伺服器 (Top-level Domain),然后再进一步问权威名称伺服器 (Authoritative)。如上图树状的结构来分组,查找就会变快很多。
当然每次都这样一层层问,很麻烦且要等传输时间,所以会有快取来处理。不过快取就会有过期的问题,例如对应的 IP 要换,就会需要等时间来让快取失效,或手动设置来让快取失效。
如果你想要测试到某个域名的联通性,可以在终端机使用 ping
指令;透过 ping
我们也可以获得到达目标机器的往返时间。这能有助于我们选择该把机器部署在哪里。举例来说,如果你的服务使用者都在台湾,假设 AWS 有东京、首尔、新加坡,这几个物理距离跟台湾都很近的机房,如果主要考量是速度,你该选哪一个呢?
这可以透过在 AWS 开三台机器,然后每台都 ping
一下来协助判断。目前社群中也有一些网站 (例如 AWS Ping Test) 直接都帮你测好,让你可以直接看。
发送请求后,资料如何传输?
前面谈到,当找到伺服器的 IP 后,浏览器会对在该 IP 位置的伺服器发送 HTTP 请求,然后伺服器会回应。然而,在这段过程中,发生了什么事? 资料是如何传输的?
具体来说,硬体层如何传送封包跟物流如何送货到你家,概念上是很类似的。就像物流通常不会直接从仓库把货运到你家,而是会先到不同的集货站,例如从国外寄送到台北,可能会先到港口,然后再把物品转去台北的集货站,然后再由送货员送到你家。
资料封包 (data packet) 的传送也一样,不会是直接送到伺服器,也不会是直接由伺服器传给客户端。在这过程中,会有非常多的路由器,然后路由器有演算法 (最短路径演算法) 来判断,然后最终传送到目的地。
分层模型
在讨论资料传输时,业界有一个 OSI (Open Systems Interconnection) 的模型在描述,从物理层 (Physical Layer) 一路到应用层 (Application Layer),例如海底电缆是物理层,我们常谈到的 HTTP 是在应用层的协定。
小赖推荐可以不用去背 OSI,但是可以思考为什么要分层? 之所以会分层,是因为这么做能让整体变得干净好维护。
举例来说今天 HTTP 发送一个 GET
请求,发到表示层 (Presentation Layer) 后,所有从应用层 (Application Layer) 送来的东西,都会被认为是同一包,然后表示层加入自己要处理的部分。这样的做法,让每层可以处理自己负责的就好,就会变得很干净好维护。
而在每一层的沟通,都需要有协定 (protocol),才能确保不同系统与通信设备之间的沟通,能够被标准化。避免每个系统都用自己的方式传资料,导致不兼容的混乱。我们常听到的 HTTP、TCP、UDP、IP 都是协定。
在 E+ 版本的摘要中,会收录小赖在直播中谈到关于 HTTP、TCP、UDP、IP 的深度内容,且搭配简报的图文好读版。有兴趣的读者欢迎订阅 E+ (连结)