Http 面试复习

284 阅读16分钟

多进程的浏览器

  1. 浏览器进程(Browser Process),这个是浏览器的主进程,主要负责包括地址栏、前进后退按钮、处理网络访问、文件访问等。
  2. 渲染进程(Renderer Process),控制显示网站的选项卡内的所有内容。
  3. 插件进程(Plugin Process),控制网站使用的所有插件。
  4. GPU(GPU Process),与其他进程隔离处理GPU任务,由于GPU处理来自多个应用程序的请求并将它们绘制在同一表面上,因此将其分为不同的过程。
  5. 网络进程(NetWork Process),负责页面的网络资源加载,之前是放在浏览器进程中的一个线程运行,现在独立出来。

浏览器的渲染进程是多线程的

  1. GUI 渲染线程
  2. JS 线程
  3. 事件触发线程
  4. 定时器触发线程
  5. 异步http 请求线程

URL结构组成部分

它由 协议、域名、端口、路径名称、查询字符串、锚点

protocol://host:port/pathname?query=1&name=2#fragment

protocol     - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,
               其中最常见的类型是 http,而 https 则是进行加密的网络传输。
host         - 定义域主机(http 的默认主机是 www)
domain       - 定义因特网域名,比如 google.com
port         - 定义主机上的端口号(http 的默认端口号是 80)
path         - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
filename     - 定义文档/资源的名称
query        - 查询参数,即 ? 后的参数值 query=1&name=2
fragment     - 即 # 后的hash值(fragment),一般用来定位到某个位置

从输入 URL 到页面加载完成的过程

1.处理输入url信息

  1. 如果为非url结构的字符串,交给浏览器默认引擎去搜索改字符串;
  2. 若为url结构的字符串,浏览器主进程会交给 网络进程 ,开始干活。

2.查找浏览器缓存

网络进程会先看看是否存在本地缓存,如果有就直接返回资源给浏览器进程,无则下一步 DNS-> IP -> TCP

3.DNS解析

网络进程拿到url后,先会进行DNS域名解析得到IP地址

DNS解析过程:域名解析包含两种查询方式,分别是(递归查询)和(迭代查询

迭代查询:

image.png

  1. 浏览器的 DNS 缓存中去查询是否有对应记录,如果缓存中有,这个解析过程就结束
  2. 查找操作系统hosts文件,如果没有找到则把域名发送给本地DNS服务器,如果配置中有,这个解析过程就结束
  3. 本地DNS服务器如找到则返回IP地址,否则转发给根DNS服务器本地DNS服务器是连接WIFI的运营商分配的IP地址,运营商存储了大量域名对应的IP地址,所以才能返回对应相应IP
  4. 根DNS服务器返回给本地DNS服务器一个顶级DNS服务器地址如.com、.cn、.org等
  5. 本地DNS服务器顶级DNS服务器发送解析请求并返回Name Server域名服务器的地址( Name Server相当于是 www.baidu.com )
  6. Name Server域名服务器会查询存储的域名和IP的映射关系表,再IP地址返回,由此结束流程

递归查询:

yuque_diagram.jpg

  1. 主机首先向其本地域名服务器进行查询。
  2. 本地域名服务器收到递归查询的委托后,也采用递归查询的方式向某个根域名服务器查询。
  3. 根域名服务器收到递归查询的委托后,也采用递归查询的方式向某个顶级域名服务器查询。
  4. 顶级域名服务器收到递归查询的委托后,也采用递归查询的方式向某个域名服务器查询。
  5. 域名服务器查询到相应IP地址后,递归返回给上一层顶级域名服务器,直到本地DNS服务器

DNS 缓存

当某一台 DNS 服务器接收到一个 DNS 应答时,它就能够将映射缓存到本地,下次查询就可以直接用缓存里的内容。缓存并不是永久的,每一条映射记录都有一个对应的生存时间,一旦过了生存时间,这条记录就应该从缓存移出。 有了缓存,大多数 DNS 查询都绕过了根 DNS 服务器,需要向根 DNS 服务器发起查询的请求很少。

4.TCP三次握手

接下来就是利用IP地址和服务器建立TCP连接。连接建立之后,向服务器发送http请求。(如果请求协议是HTTPS,那么会先建立TLS连接)

5.服务器响应

服务器收到请求信息后,会根据请求信息生成响应行、响应头、响应体,并发给网络进程。网络进程接受了响应信息之后,就开始解析响应头的内容。

网络进程解析响应行和响应头信息的过程:

  1. 重定向:如果响应行状态码为301(永久重定向)和302(临时),那么说明需要重定向到其他url。这时候网络进程会从响应头中的Location字段里读取重定向的地址,并重新发起网络请求。
  2. 响应数据处理:导航会通过请求头的Content-type字段判断响应体数据的类型。浏览器通过这个来决定如何显示响应体的内容。 比如:若为application/octet-stream,则会按照下载类型来处理这个请求,导航结束。若为text/html,这就告诉浏览器服务器返回的是html格式,浏览器会通知渲染进程,你要干活了。

6.浏览器解析渲染页面

  1. 解析HTML,构建DOM树
  2. 解析CSS,生成CSS规则树
  3. 合并DOM树和CSS规则,生成render树
  4. 调用GUI渲染线程绘制render树(paint)

image.png

HTTP相关问答

为什么需要三次握手?

  1. 不能确认服务器端和客户端双方的发送能力接收能力
  2. 无法防止历史连接的建立
  3. 也无法可靠的同步双方序列号
  4. 若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源

Post 和 Get 的区别

  1. Get 请求能缓存,Post 不能
  2. Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但是在抓包的情况下都是一样的。
  3. Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术
  4. URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
  5. Post 支持更多的编码类型且不对数据类型限制

常见状态码

2XX 成功

  1. 200 OK,表示从客户端发来的请求在服务器端被正确处理
  2. 200 OK:请求成功,响应的主体部分将包含所请求的资源。
  3. 201 Created:请求成功,并且服务器已创建了新的资源。
  4. 204 No Content:请求成功,但没有要返回的资源。

3XX 重定向

  1. 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
  2. 302 found,临时性重定向,表示资源临时被分配了新的 URL
  3. 303 see other,表示资源存在着另一个 URL
  4. 304 not modified,如果资源未被修改,可以使用缓存的版本,通常与 Etag/If-None-Match 或 Last-Modified/If-Modified-Since 配合使用。

4XX 客户端错误

  1. 400 bad request,请求报文存在语法错误
  2. 401 unauthorized,需要身份验证,或者认证已经被拒绝。
  3. 403 forbidden,表示对请求资源的访问被服务器拒绝
  4. 404 not found,表示在服务器上没有找到请求的资源

5XX 服务器错误

  1. 500 internal sever error,表示服务器端在执行请求时发生了错误
  2. 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
  3. 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

缓存机制

强缓存

是否使用强缓存由HTTP的三个头部字段来控制:ExpiresPragmaCache-Control

Exipres字段是Http/1.0中的字段,其优先级在三个缓存控制字段中最低。

image.png

如图所示,响应头中Expires的值是一个时间戳,发起请求时,如果本地系统时间在这个时间戳之前,则缓存有效,否则缓存失效,进入协商缓存。若该响应头中Expires设置为无效的日期,比如 0, 则代表着过去的日期,即该资源已经过期。

Cache-Control是 HTTP/1.1 中规定的通用头部字段,常用属性如下:

image.png

  1. no-store:禁止使用缓存,每次请求都去服务端拿最新的资源;
  2. no-cache:不使用强缓存,直接进入协商缓存模块,向服务端请求校验资源是否“新鲜”;
  3. private:私有缓存,中间代理服务端不可缓存资源
  4. public:公共缓存,中间代理服务端可以缓存资源
  5. max-age:单位:秒,缓存的最长有效时间。其起始时间为缓存时响应头中的Date字段,即有效期到responseDate + max-age,发起请求时超过该时间则缓存过期。
  6. must-revalidate:缓存一旦过期,则必须重新向服务端验证。

协商缓存

强缓存过期或者请求头字段设置不走强缓存,则进入协商缓存部分。协商缓存涉及两对头部字段,分别是Response Header下的(ETag)、Request Header下的(If-None-Match)和Response Header下的(Last-Modified)、Request Header下的(If-Modified-Since)

ETag/If-None-Match

ETag/If-None-Match 的值是一串hash值(hash算法不统一),是资源的标识符,当资源内容发生变化,其hash值也会改变。其过程与上面的相似,不过服务端是比较服务端资源的hash值和请求头中的If-None-Match的值,但比较方式有所区别,因为ETag有两种类型:

Last-Modified/If-Modified-Since

Last-Modified/If-Modified-Since的值是资源修改时间。第一次请求资源时,服务端将资源的最后修改时间放到响应头的 Last-Modified 字段中,第二次请求该资源时,浏览器会自动将该资源上一次响应头中的Last-Modified的值放到第二次请求头的If-Modified-Since字段中,服务端比较服务端资源的最后一次修改时间和请求头中的If-Modified-Since 的值,如果相等,则命中缓存返回 304,否则,返回200。

两者区别

  1. ETag/If-None-Match优先级比Last-Modified/If-Modified-Since高;
  2. Last-Modified/If-Modified-Since有个1S问题,即服务端在1S内修改文件,且再次受到请求时,会错误的返回304

流程图

image.png

http 1.0特征

优点

  1. http/1.0 相对来说是比较简单的, 基本的报文是 请求头加上请求体(header + body),头部信息也是 key-value的简单是形式;
  2. http 1.0 是灵活并且易拓展的, 协议中的请求方法, url, port, 和头部信息等都可以由开发人员自行规定。
  3. 跨平台的,http 出现带来的最大的好处就是跨平台,只要你满足我的传输协议,就可以不限制平台,这也使得http的应用变的非常多,从以前的 C端, 到现在B端等

缺点

  1. http传输是无状态的,意味着如果不做状态处理,那么谁都可以访问服务器,毕竟服务又不认识人。解决这种办法有cookie, session, token, 到后来的jwt等
  2. 明文传输。这里纠正一个概念,不是说使用get传输方式就是明文传输。post在也是一样的,我们在调试的时候都可以通过抓包工具来获取到对应的数据包。明文传输无疑是在将自己的信息在互联网上裸奔。解决这个明文传输的方式那就是 https,https 就是基于http是可拓展的基础上,在tcp 和 http之间,增加了一个ssl/tls层。
  3. http 1.0 还有一个最要命的缺点是他的网络响应方式,串行响应的模式,必须要等上一次请求回来才能对下一个请求进行响应。这里如果上一个请求卡死了,那么就会导致整个网站卡死,获取不到数据,这种行为也叫做 队头阻塞,还有就是每一次的网络请求都需要做三次握手和四次挥手,没有长连接是一个很大的问题。

http 1.1

http 1.1 主要解决是

  • HTTP1.0 每一次连接都需要三次握手和四次挥手(每一次发送请求都要等前一次请求回来后),而且是串行的请求方式,增加额外的通信开销;
  • 解决http1.0无法长连接的问题

长连接

在http 1.1 中可以通过在请求头中的 connection:keey-alive 来告诉服务器我当前需要使用长连接的方式(持久连接)。这样做的好处是于减少了TCP 连接的᯿复建⽴和断开所造成的额外开销,减轻了服务器端的负载。

持久连接的特点是,只要任意⼀端没有明确提出断开连接,则保持 TCP 连接状态。

image.png

管道⽹络传输

基于 http1.1 中有长连接的功能,成就了管道传输pipeline

管道传输的概念是,每一次请求我都可以不用等前面的请求响应结束后,我再来请求后面的请去。具体的图像图下:

image.png

这种管道的传输方式也是需要按照请求的顺序来返回的。「请求 - 应答」的模式加剧了 HTTP 的性能问题。 容易发生队头阻塞

http/1.1 的瓶颈

  1. 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端⼀直请求不到数据,也就是队头阻塞
  2. 没有请求优先级控制;
  3. 请求只能从客户端开始,服务器只能被动响应;
  4. 请求 / 响应头部(Header)未经压缩就发送,⾸部信息越多延迟越⼤。只能压缩 Body 的部分; 5.每次互相发送相同的⾸部造成的额外的通信开销。

HTTP/2.0做了哪些改进?

二进制分帧

二进制分帧就是将一条连接上所有传输的信息,分割为更小的消息和帧,并对他们采用二进制格式编码,首部信息放在Headers帧中,主体信息被封装在Data帧中。

问题解答:

  1. 为什么HTTP/2.0可以对所有的内容进行二进制转换?

因为二进制分帧层在应用层和传输层之间的中间层,所有信息都会经过,进而可以转换。

  1. 为什么要用二进制?

效率更高,计算机更青睐二进制数

多路复用

多路复用技术就是可以并行发送请求,而且无需等待响应返回的一种技术,消除了不必要的延迟,减少了页面加载时间。

问题解答:

  1. HTTP/2.0多路复用与HTTP/1.1中管道的区别在哪?

管道也可以并行发送请求,但是返回响应结果则必须是发送时的顺序,而多路复用技术不需要等待,不容易造成堵塞。多路复用的基础就是二进制分帧,因为可以乱序发送和接收。

首部压缩

在第一次请求之后,大部分的字段可以复用的。而且随着页面越来越复杂,同一个页面发出的请求会越来越多。如果头部不压缩的话,会造成很大的流量开销

问题解答:

  1. 首部压缩的原理? 支持http2.0的浏览器和服务器会维护一个相同的静态表和一个动态表,以及内置一个霍夫曼编码表。静态表存储的是常见的一些头部,和一些很常见的头部键值对,例如method:get以及cookie。动态表开始是空的,如果头部命中静态表中的名称,那么就回将这份键值对加入动态表中,例如cookie:xxxx。这样做的原因在于,请求或则响应头命中了静态或者动态表的时候,只需要一个字节就能表示,可想而知,这个字节就是一个地址,指向表中的数据。

image.png

服务器推送

服务器可以对一个客户端请求发送多个响应,例如,浏览器向服务端请求index.html,里面包含一张样式表和一张图片。传统的方法就是会向浏览器发送三次请求。而服务端推送,则可以在一次请求内将这三个文件全部发送给浏览器,减少了请求次数,提升了网页性能。

问题解答:

  1. 服务器推送有什么弊端?

如果服务端推送的内容,浏览器有缓存的话,就会浪费带宽。避免的方法就是在服务端配置,只对第一次请求实现服务器的推送。

HTTPS相对于http有什么优缺点

优点

  1. SEO方面:采用https加密的网站在搜索结果中的排名将会更高。
  2. 安全:https协议是由SSL+http协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。

缺点

HTTPS协议握手阶段比较费时,连接缓存不如HTTP高效,会增加数据开销和功耗