浏览器HTTP访问全过程

一 背景

这是一道经典面试题,我在面试别人的时候也常拿这道题来考察面试者的知识面,无论是做前端还是后端,这都是必须掌握的一个过程。现在性能优秀的网站已经能做到毫秒级别的响应速度了,但就是在这样极短的时间内,浏览器和服务端已经进行了多次的交互了,而其中的技术涉及面是非常广的。本人就此过程涉及到的主要环节进行了刨析。

二 DNS域名解析

域名解析通常是网站访问的第一步,这一步的目的主要是将我们的域名解析为对应的IP地址,通过IP地址找到服务器建立连接。域名解析的过程主要为以下几步:

  1. 浏览器会首先检查自己是否有这个域名的缓存(浏览器会将自己访问过的域名的IP缓存一份,这也是为什么第二次访问往往比第一次访问快的原因之一)。如果有,则解析结束。

  2. 如果浏览器的缓存没有命中的话,浏览器会检查操作系统缓存中是否有对应的解析结果。操作系统也是有域名解析过程的,在Windows系统中,这个路径“C:\Windows\System32\drivers\etc”下的hosts文件里就是存放的域名与IP地址的对应关系。

    # localhost name resolution is handled within DNS itself.
    
    #	127.0.0.1       localhost
    
    #	::1             localhost
    

    黑客一般通过修改你的hosts文件里的内容,把特定的域名解析到他指定的IP地址上,即域名劫持。

  3. 如果至此还没有命中域名,才会正在的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你城市的某个角落,距离你不会太远,并且这台服务器的性能很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。

  4. 如果LDNS仍然没有命中,就直接跳到Root Server域名服务器请求解析。

  5. 根域名服务器返回给LDNS一个所查询域的主域名服务器地址。

    主域名服务器:gTLD Server,国际顶尖域名服务器,如.com .cn .org等

  6. 此时LDNS再发送请求给上一步返回的主域名服务器。

  7. 接受请求的主域名服务器查找并返回这个域名对应的Name Server的地址,这个地址就是网站注册的域名服务器。

  8. Name Server根据映射关系表找到目标IP,返回给LDNS

  9. LDNS缓存这个域名和对应的IP,并缓存。

  10. LDNS把解析的结果返回给用户,用户缓存到本地,域名解析过程到此结束。

拿到域名对应的IP地址后,浏览器就要可以发起HTTP请求了。

三 HTTP请求

HTTP请求方法对照表

HTTP响应头和请求头信息对照表

HTTP状态码对照表

HTTP Content-type 对照表

深入理解HTTP协议

四 TCP连接

HTTP Request/Response是通过TCP连接来发送和接收的。想要建立TCP连接,需要知道:本机IP、本机端口、服务器IP、服务器端口。

HTTP的端口默认是80,HTTPS默认是443

经过三次握手以后,客户端和服务器端的TCP连接就建立起来了!

TCP连接

五 网络层

IP协议的作用是把TCP分割好的各种数据包传送给接收方。而要保证确实能传到接收方还需要接收方的MAC地址,也就是物理地址。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。ARP协议可以将IP地址解析成对应的MAC地址。当通信的双方不在同一个局域网时,需要多次中转才能到达最终的目标,在中转的过程中需要通过下一个中转站的MAC地址来搜索下一个中转目标。

六 数据链路层

在找到对方的MAC地址后,就将数据发送到数据链路层传输。这时,客户端发送请求的阶段结束。

七 Web服务器

当HTTP请求到达服务器端,Web服务器会首先进行处理。一般服务器会通过epoll的方式监视所有的连接,当连接的状态发生变化(如有数据可读),才用一个进程/线程对那个连接进行处理,处理完以后继续监视,等待下次状态变化。nginx就是利用这样的机制来工作的,

以nginx处理为例,它首先会判断这个请求时静态的请求还是动态的。

  • 对于静态的请求(HTML文件、JS文件、CSS文件、图片等),一般直接读取本机硬盘上的相关文件,直接返回。

  • 如果时动态的请求,需要后端服务器(如Tomcat)处理以后才能返回,那就需要向Tomcat转发。现在的Tomcat一般不止一个,那就需要安装某种策略选取一个。

    ngnix支持的策略有:

    • 轮询:按照次序挨个向后端服务器转发
    • 权重:给每个后端服务器指定一个权重,相当于向后端服务器转发的几率。
    • ip_hash: 根据ip做一个hash操作,然后找个服务器转发,这样的话同一个客户端ip总是会转发到同一个后端服务器。
    • fair:根据后端服务器的响应时间来分配请求,响应时间短的优先分配。

    不管用哪种算法,某个后端服务器最终被选中,然后nginx需要把HTTP Request转发给后端Tomcat,并且把Tomcat输出的Http Response再转发给浏览器。

由此可见,nginx再这种场景下是一个代理人的角色。

nginx转发过程

八 应用服务器

应用服务器就是根据用户的不同请求做不同处理的,一般会涉及到数据的增删改查,因此这以阶段还需要和数据库打交道。

这部分是一般是程序开发的核心,后端开发一般主要就是写这部分的逻辑。

九 浏览器渲染

浏览器收到了Http Response,从中读取了HTML页面,开始准备显示这个页面。但是这个HTML页面中可能引用了大量的其他资源,例如js文件、CSS文件、图片等,这些资源也位于服务器端,因此这时浏览器还需要再去一个一个下载,从我们最开始解析DNS开始,把这前做过的事再来一遍。

如果需要下载的外部资源太多,浏览器会创建多个TCP连接,并行地去下载。

同一时间对同一域名下的请求数量也不能太多,要不然服务器访问量太大,受不了。所以浏览器要限制一下, 例如Chrome在Http1.1下只能并行地下载6个资源。

当服务器给浏览器发送JS,CSS这些文件时,会告诉浏览器这些文件什么时候过期(使用Cache-Control或者Expire),浏览器可以把文件缓存到本地,当第二次请求同样的文件时,如果不过期,直接从本地取就可以了。

如果过期了,浏览器就可以询问服务器端,文件有没有修改过?(依据是上一次服务器发送的Last-Modified和ETag),如果没有修改过(304 Not Modified),还可以使用缓存。否则的话服务器就会被最新的文件发回到浏览器。

现在浏览器得到了三个重要的东西:

  1. HTML ,浏览器把它变成DOM Tree
  2. CSS, 浏览器把它变成CSS Rule Tree
  3. JavaScript, 它可以修改DOM Tree

浏览器会通过DOM Tree和CSS Rule Tree生成所谓“Render Tree”,计算每个元素的位置/大小,进行布局,然后调用操作系统的API进行绘制。

至此,我们终于可以再浏览器中看到网页的内容了。

posted @ 2021-02-23 23:19  bGpi  阅读(1044)  评论(0编辑  收藏  举报