访问URL的过程。

148 阅读6分钟

前言

这个问题考察点很多,以下列举了主要的问题,如果再深入的话......

  • URL解析,为什么要解析?
  • DNS解析,解析的流程是什么?
  • 三次握手,为什么两次不行?
  • 四次挥手,为什么三次不行?
  • 怎么优化?聊一下强缓存和协商缓存?
  • 浏览器解析渲染页面的过程?
  • Http1.0、Http1.1、Http2.0的区别?

以下是我自己的理解和大佬们的借阅


一. url解析

为什么要解析(编码)

因为网络标准规定URL只能是字母和数字,特殊符号需要进行转译。

encodeURI()encodeURIComponent()方法都可以对URI(通用资源标识符)进行编码,以便发送给浏览器。但它们编码的范围有所不用。

encodeURI是针对没参数的链接地址

encodeURI("https://juejin.cn/?aaa= asd  ");
输出:'https://juejin.cn/?aaa=%20asd%20%20'

encodeURIComponent是针对参数进行编译,它的编译范围广

encodeURIComponent("https://juejin.cn/?aaa= asd  ");
输出:'https%3A%2F%2Fjuejin.cn%2F%3Faaa%3D%20asd%20%20'

二.域名解析,DNS解析出IP地址

  1. 浏览器DNS缓存记录,比如chrome的,chrome://net-internals/#dns
  2. 操作系统的DNS缓存,终端输入ipconfig/displaydns可查看缓存。
  3. hosts文件查询记录。自己也可以在hosts文件配置域名和ip的映射关系。
  4. 运行商服务器是否有记录,比如电信、移动、联通。
  5. 根DNS服务器查询。比如"www.juejin.com",会先去.根域名服务器查找,然后通知顶级域名服务器.com查找,再到www.juejin.com二级域名服务器查找。

优化

  1. 减少dns查询

  2. 默认情况下浏览器会对页面中和当前域名不在同一个域的域名进行预获取,并且缓存结果,这就是隐式DNS解析。如果后面有较大可能访问的跨站资源时,在link标签添加 dns-prefetch 和 href解析地址 ,称为显示DNS解析

    <meta http-equiv="x-dns-prefetch-control" content="on" />//开启dns预解析
    <meta http-equiv="x-dns-prefetch-control" content="off" />//关闭dns预解析
    <link rel="dns-prefetch" href="http://www.xxx.com" />
    

三.3次握手

  • 第一次握手:客户端发送SYN包(seq = x)到服务端,并进入SYN_SENT状态,等待服务端确认。
  • 第二次握手:服务端收到客户端的SYN包(seq = x),同时自己也发送一个SYN包(seq=k)ACK确认包(ack=x+1),即SYN+ACK包,服务端进入SYN_RECV状态。
  • 第三次握手,客户端收到服务端的SYN+ACK包,向服务端发送确认包ACK(ack=k+1),客户端和服务端进入TCP连接成功状态。

三次握手.png

问:为什么两次握手不行?

因为两次的话,服务端不知道客户端是否有接收到信息。

四. 4次挥手

  • 客户端发送FIN(seq=n) 给服务端
  • 服务端收到FIN后,发送ACK(ack=n+1)确认包
  • 服务端发送FIN(seq=m) 给客户端
  • 客户端收到FIN后,发送ACK(ack=m+1)确认包

四次挥手.png

问:为什么三次不行?

因为第二次挥手时,服务器可能资源还没发送完,不能立即关闭。所以等到能关闭的时候再进行第三次挥手

五. 怎么优化?聊一下强缓存和协商缓存?

强缓存->协商缓存->服务器资源

  • 浏览器在加载资源时,http header判断是否命中强缓存,命中,则从缓存中读取资源,不会发请求到服务器。(优先内存、再磁盘)就是我们平时看到的 memory cache内存中 或者 disk cache磁盘中。内存速度比磁盘块,关掉进程就是杀死内存。根据磁盘缓存持久。
  • 强缓存没有命中时,浏览器会发送一个请求到服务器,通过服务器端依据资源的http header验证这个资源是否命中协商缓存,如命中,则服务器会将这个请求返回,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从自己的缓存(内存或者磁盘)中去加载这个资源。
  • 强缓存与协商缓存的共同点是:如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;区别是:强缓存不发请求到服务器,协商缓存会发请求到服务器。
  • 当协商缓存也没有命中的时候,浏览器直接从服务器加载资源数据。

强缓存和协商缓存.jpg

强缓存

Expire(http1.0):绝对时间,缺点:服务器时间和客户端时间不一致就会有问题

Cache-Control(http1.1优先级高):相对时间,max-age:300,表示缓存300秒。Cache-Control 除了max-age ,还有其他参数配置

  • no-cache:不做强缓存,做协商缓存
  • no-store:获取新资源
  • public(默认):浏览器和cdn代理服务器都缓存
  • private:仅浏览器缓存

协商缓存

Last-Modified / If-Modified-Since (http1.0)文件最后修改时间。

Etag / If-None-Match (http1.1)由服务器为每个资源生成的唯一标识,只要资源变化这个值就会变化。


六. 浏览器解析渲染页面的过程

  • 浏览器解析Html文件,生成DOM树cssOM树。DOM和CssOM是同时生成的,并不会相互阻塞,但是会阻塞DOM的渲染。
  • 合并DOM树和CssOM树生成render树(渲染树)
  • 重排,通过元素的几何信息来定位、大小的排列。
  • 重绘,绘制元素信息color、background-color等,之后完成页面的渲染。

Html解析过程中,遇到script标签。

- 当html解析过程中,遇到js脚本时,会阻塞html的解析,js脚本加载并执行完成,才会继续解析html。
- script标签的async和defer属性,都是异步请求js,不会阻塞html的解析。
- async:js脚本请求成功后,需要执行完js脚本,才会继续解析html。
- defer:js脚本请求成功后,会继续解析html,再执行js脚本。

七. Http1.0、Http1.1、Http2.0的区别?

Http1.0和Http1.1

  1. 上面说到的缓存升级 强缓存协商缓存的优化。Expire->cache-controllast-Modified/Etag
  2. HTTP/1.1新增了错误状态响应码
  3. HTTP/1.1中默认开启 Connection: keep-alive,即TCP连接默认不关闭,可以被多个请求复用。
  4. HTTP/1.1中引入了管道机制(pipelining),即在同一个TCP连接中,客户端可以同时发送多个请求

Http1.1缺点

Http1.1虽然TCP保持持久连接,并且可以发送多个请求,但是所有请求都是同步进行,请求资源慢时,会造成阻塞。

Http2.0

Http2.0需要是https安全协议下才能生效,他解决了Http1.1的性能问题

  1. 首部压缩,当首部数据量大的时候,性能提升还是很不错的。
  2. 多路复用,在一个连接里同时发送多个请求。6个?
  3. 服务端推送:HTTP/2 允许服务器未经请求,主动向客户端发送资源。常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。