在浏览器的地址栏上键入URL后并回车后,究竟发生了什么?

Published on in 网络 with 0 views and 0 comments

本来想整理一篇关于HTTP协议或HTTPS协议的文章,但看到网上有很多经典的文章很好地阐述了这两个协议,所以也就没有花时间自己再去做整理,推荐两篇阮一峰老师的文章:

· HTTP 协议入门
· SSL/TLS协议运行机制的概述


“在浏览器的地址栏上键入URL后并回车后,究竟发生了什么?”想必类似的问题很多小伙伴在面试时都被问到过,今天我就来总结一下这个回车键背后的故事。

其实这个问题在《计算机网络自顶向下方法》一书的第五章5.7节也有非常详细的阐述,本文也是参考它做的一个总结。

现在Jeffrey的笔记本电脑已经获取了IP地址(忽略DHCP的过程),Jeffrey在浏览器的地址栏中输入了 www.google.com 之个地址后:

0. 补齐URL

一个完整的URL是长这样的 https://www.google.com 其可以分为如下几个部分:

  • 协议:https
  • 主机名:www
  • 域名:google.com

现在Jeffrey在浏览器地址栏输入了 www.google.com 没有加上协议,但是浏览器很智能一般默认不指定协议的话,以chorme为例它会为其补上HTTP协议,也就是说现在的URL是这样的 http://www.google.com

1. 查找浏览器的DNS缓存

域名这个设计是为了让人们能够以人们见名知意的方式熟记URL,而计算机在建立连接时,可没有人们那么花里胡哨,什么xxx.wtf,计算机连接只认IP地址,所以在客户端和服务器连接之前需要把域名解析为IP地址,这会就少不了DNS服务器服务。

有DNS的地方就有缓存,DNS可以说是一个精心设计的分布式数据库,有数据库当然得有缓存数据库,那浏览器自身也是会缓存我们的DNS记录的,以chorme为例,输入 chrome://net-internals/#dns 可以查看当前浏览器下的缓存。

2. 查找主机本地的DNS缓存

查完浏览器的DNS缓存后发现没有,此时就需要查找主机本地的DNS缓存,此时就需要查看本地的hosts文件里的DNS缓存记录,文件地址:

  • Windows:C:\Windows\System32\drivers\etc\hosts
  • Linux:/etc/hosts

3. DNS请求域名的IP地址

当这两种缓存查找都没要找到Jeffrey同学想要的域名对应的IP地址时,才向DNS服务器发起DNS请求。

将一个DNS查询报文,封装在目的端口为UDP:53的报文段中,此时报文被丢出首先要到达网关,但是如果主机不知道网关的MAC地址时,只能再向局域网中广播一个ARP查询报文才行。

当把这个DNS查询报文顺利丢给了Jeffrey的网关地址时,主机向本地DNS服务器做的查询叫做递归查询,网关路由器则会查看主机的路由表信息找到DNS服务器,假设是学校的DNS服务器(也称本地域名服务器),主机向本地DNS服务器做的查询叫做递归查询,即时本地DNS服务器没有这个记录,它也会以客户端的身份向另外的DNS查询该域名的记录。此时学校服务器还真的居然没有 www.google.com 这个域名的记录(我也是惊了)。

好的那不着急,此时我们的本地域名服务器会采取迭代查询,先向根域名服务器请求一次,之后根域名服务器会告诉我们的本地域名服务器下一级要查询的服务器是.com,以此按域名树的方式迭代一层层查询:

image.png

查到域名的解析值后,服务器通过DNS回答报文,并通过递归查询逐层地返回给客户机。

4. 建立TCP连接

如果熟悉HTTP协议的同学都知道,HTTP协议是建立在TCP协议之上的。经过各种路由协议的洗礼之后到达了 www.google.com 的IP所对应的服务器(这里要说一句,不考虑CDN的情况,CDN会为我们的服务器多加一层代理)。

建立TCP连接,离不开TCP的三次握手,三次握手是为了确认连接能够正常建立,这一过程就像发微信前互相要来一句“在吗?”,下面是TCP三次握手的状态迁移图:

image.png

建立成功后状态变为ESTABLISHED,此时服务器和客户端才能进行更上层的协议交互。

5. 通过HTTP协议发送请求

此时Jeffrey的主机已经和目标服务器建立了一个具有目标端口为80的TCP连接,这时候才真正轮到HTTP协议上场,协议说白了就是一种契约,让互相交流的两方都能理解的契约,而HTTP协议的格式是这样的:

image.png

www.google.com HTTP服务器读取到了从TCP套接字读取的HTTP GET报文,并生成一个HTTP响应报文返回给Jeffrey的主机,浏览器通过读取HTTP响应体重的HTML渲染出了谷歌页面,整个奇妙的旅程也就结束了。


标题:在浏览器的地址栏上键入URL后并回车后,究竟发生了什么?
作者:Jeffrey