浏览器输入网址到显示网页的全过程
只要你面过IT相关的岗位,不管是前端、后端还是测试,绝对被问过这道堪称“祖师爷级别”的经典面试题:
“从浏览器输入一个网址,到屏幕上显示出网页,期间到底发生了什么?”
这个问题之所以经典,是因为它就像一根糖葫芦的签子,能把计算机网络里的 DNS、TCP、HTTPS、HTTP 以及浏览器的渲染机制全部串起来。
如果你去背教科书,那些七层模型、底层协议绝对能把你绕晕。今天,咱们就抛开枯燥的术语,用大白话把这段“极其奇妙的网络大冒险”彻底盘清楚。
第一步:找路(DNS 域名解析)
你在浏览器里敲下了 www.taobao.com,然后潇洒地按下回车。
但问题来了:计算机是个只认数字的死脑筋,它根本不知道“taobao”是个什么鬼,它只认识 IP 地址(比如 114.55.205.139)。
这时候,就需要找人翻译 了。这个翻译的过程,就叫 DNS 解析。
这就好比你想去一家叫“老王烧烤”的店,但你不知道具体在几弄几号,于是你开始查地图 。
浏览器找 IP 地址的过程是非常卑微的,它会一层一层地去问:
查自己:浏览器先看看自己的缓存里有没有记录过这个域名的 IP。
查电脑系统:如果浏览器忘了,就去问操作系统的缓存(也就是本地的 hosts 文件)。
查路由器:如果电脑也不知道,就去问你家里的路由器。
查当地电信局(本地域名服务器):路由器也不知道,只能去问给你提供网络的运营商了
查户籍科(根域名服务器):如果运营商的缓存里也没有,那就会在全球的 DNS 数据库里一级一级往下查,直到找到那个唯一的 IP 地址,然后把结果一层层返回给浏览器。
拿到 IP 地址的那一刻,浏览器终于长舒一口气:“兄弟们,找到目标坐标了!”
第二步:修路打招呼(TCP 三次握手)
拿到坐标后,能直接把数据扔过去吗?不行。
网络世界里危机四伏,在正式传数据之前,浏览器必须先和服务器“通个电话”,确认对方是不是活着的,这就是大名鼎鼎的 TCP 三次握手。
你完全可以把它理解为一段极其谨慎的电话开场白:
浏览器(第一次握手):“喂,淘宝服务器,你在家吗?我能和你建立连接吗?”(发送 SYN 包)
服务器(第二次握手):“我在家呢!我准备好了,你那边的网络也能正常收到我说话吗?”(发送 SYN + ACK 包)
浏览器(第三次握手):“听得清!那咱们马上开始传数据吧!”(发送 ACK 包)
经历了这三次确认,双方都确定了对方能听、能说,一条可靠的数据传输通道 这才算正式修好。
第三步:对暗号(TLS/SSL 握手)
注意,如果你的网址是 http:// 开头的,那修好路就直接开始传数据了。
但现在的网站基本都是安全的 https:// 开头。这就意味着,在 TCP 修好路之后,还得额外加一道极其严格的安检程序。
服务器会先向浏览器出示自己的数字证书(相当于身份证),证明自己确实是真淘宝,不是钓鱼网站。
确认身份后,双方会在网络上偷偷协商出一个只有彼此知道的**“接头暗号”(对称加密密钥)**。
以后的所有聊天内容,全都用这个暗号加密。哪怕黑客在半路把网线剪了,把数据全截获过去,看到的也只是一堆无法破解的乱码。
第四步:点菜(发送 HTTP 请求)
路修好了,暗号也对上了,浏览器终于可以把你的要求告诉服务器了。
它会打包一个 HTTP 请求报文,这个报文就像是一张点菜单,里面写着:
动作(Method):我要拿东西(GET)。
目标(URL):我要拿首页的 HTML 文件(/)。
身份证明(Cookie):顺便带上我上次登录的凭证,别让我重新输入账号密码了。
自身情况(User-Agent):告诉服务器我是用的谷歌浏览器,还是苹果手机上的 Safari,方便服务器给我排版。
这张“点菜单”顺着刚才修好的 TCP 通道,一路飞奔,抵达了淘宝的服务器。
第五步:厨房做菜并上菜(服务器处理并响应)
淘宝的服务器(比如 Nginx、Tomcat)收到了这张点菜单。
后端的 Java 或 Go 代码开始疯狂运转:它去数据库里查出你最近买过的东西、查出今天首页要推荐的商品,然后把这些数据全都塞进一个 HTML 文件里。
菜做好了,服务器会打包一个 HTTP 响应报文 给浏览器端端正正地端回去。
这个报文里第一行通常会写着:HTTP/1.1 200 OK。
(200 就是状态码,代表大吉大利,一切顺利;如果是 404,就说明你点的菜店里没有;如果是 500,就说明厨房爆炸了,后端代码报错了。)
在这个 200 OK 的下面,就是一长串的 HTML 代码文本。
第六步:摆盘上桌(浏览器渲染页面)
别以为拿到 HTML 代码就结束了。你总不能让用户盯着一屏幕的尖括号 <p> <div> 看吧?
最后一步,也就是浏览器最苦逼的“画图”工作开始了:
解析 HTML(搭骨架):浏览器把 HTML 代码一行行读下来,构建出一棵 DOM 树(这就好比盖房子,先把钢筋骨架搭起来)。
解析 CSS(刷油漆):遇到 CSS 样式,浏览器会构建出一棵 CSSOM 树(决定字有多大、背景是什么颜色)。
合并渲染树(结合):骨架和油漆结合,生成最终的 Render Tree(渲染树)。
布局和绘制(Layout & Paint):计算出每个按钮、每张图片在屏幕上的准确位置(精确到像素点),然后调用电脑的显卡,把五颜六色的画面“画”在你的显示器上。
在这个过程中,如果浏览器在 HTML 里发现了图片的链接、JS 脚本的链接,它还会偷偷开启新的线程,再去向服务器要这些文件(重新走一遍请求流程)。等到所有的 JS 执行完毕,图片加载出来,你眼前的网页就彻底活过来了!
尾声:挥手告别(TCP 四次挥手)
当整个网页都加载完毕,你开始在页面上开心地买买买时,底层的那条 TCP 连接如果长时间不用,为了不占着茅坑不拉屎,双方就会礼貌地断开连接。这就是四次挥手:
“我要断开了哦。”
“好的,我知道了,等我把最后一点东西传完。”
“我传完了,我也准备断开了。”
“好的,拜拜!”
总结
以后面试官再问起这个问题,你就在脑子里过一遍这个场景:
查地图找地址(DNS) -> 打电话修路(TCP) -> 对暗号防窃听(HTTPS) -> 递菜单点菜(HTTP 请求) -> 厨房做菜端上来(HTTP 响应) -> 摆盘上桌开吃(浏览器渲染)。
看似只是零点几秒的瞬间,但在网络底层的世界里,却千军万马地跑完了一场史诗级的接力赛!
参考文章:原文链接