原文链接:
1.5 万字 + 40 张图解 HTTP 常见面试题(值得收藏)_图解http 小林-CSDN博客
https://blog.csdn.net/qq_34827674/article/details/124089736?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170521531616777224478386%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170521531616777224478386&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-124089736-null-null.142%5Ev99%5Epc_search_result_base6&utm_term=http&spm=1018.2226.3001.4187一. HTTP基本概念
1. HTTP是什么
HyperText Transfer Protocol超文本传输协议,是一个在"两点"之间"传输"文字、图片、音频、视频等"超文本"数据的"约定和规范"。(可以是服务器到服务器,也可以是服务器到客户端,所以用"两点"来描述更加准确)
2. HTTP常见状态码

2xx:
200 OK:一切正常。如果不是HEAD请求,服务器返回的响应都会有body数据。
204 No Content:与200类似,但是响应头没有body数据。
206 Partial Content:应用于HTTP分块下载或断点续传,表示响应返回的body数据并不是资源的全部,而是一部分。
3xx:
301 Moved Permanently:永久重定向。请求的资源已经不存在了,需要用新的URL访问。
302 Found:临时重定向。请求的资源还在,但是暂时需要用另一个URL来访问。
(301和302会在响应头中使用Location字段,指明后续要转跳的URL,浏览器会自动重定向新的URL)
304 Not Modified:用于缓存控制,不具有转跳的含义,只是通知资源未修改(本地缓存和服务器中资源一样),重定向已存在的缓存文件(通知可以继续使用)。
4xx:
400 Bad Request:客户端的请求报文有错误,很笼统。
403 Forbidden:服务器资源禁止访问。
404 Not Found:请求的资源在服务器上不存在或没找到。
5xx:
500 Internet Server Error:服务器内部错误,很笼统。
501 Not Implemented:请求的功能还不支持(如同"即将开业,敬请期待")。
502 Bad Gateway:通常是一个服务器在做为网关或代理时返回的错误码,表示服务器正常工作,但是访问另一个服务器发生了错误。
503 Service Unavailable:服务器正忙,暂时无法响应。
3. HTTP常见字段
**Host字段:**客户端发送请求时,指定服务器的域名(一个服务器上可能有多个域名)。
**Content-Length字段:**服务器返回数据时,表明本次回应的长度。
**Connection字段:**持久连接(keep-alive)或非持久连接(close)。
**Content-Type字段:**服务器回应时,告知客户端数据是什么格式(比如Content-Type: text/html; charset=utf-8)。而在客户端请求时,使用Accept字段告知可以接受哪些数据格式(比如Accept: */*)。
**Content-Encoding字段:**说明数据的压缩方式。而客户端请求时,使用Accept-Encoding来告知可以接受什么压缩方式(比如Accept-Encoding: gzip, deflate)。
二. GET和POST
1. GET和POST有什么区别?
GET是从服务器获取指定的资源,资源可以是静态的文本、页面、图片、视频等。GET请求的参数一般写在URL中,URL只支持ASCII,所以GET的参数只允许ASCII字符。
POST是根据请求符合(报文的body)对指定的资源做出处理。POST请求所携带的数据一般写在报文的body中,可以是任意格式。
2. GET和POST方法都是安全和幂等的吗?
GET方法是安全且幂等的,因为它是"只读操作"。
POST方法会"新增或提交数据",是不安全且不幂等的。
(此处的"安全"指服务器资源不会被修改,"幂等"指多次执行操作的结果相同)
三.HTTP缓存技术
1. HTTP缓存的实现方式
对于重复性的HTTP请求,把"请求-响应"的数据缓存在本地,下次可以直接读取本地缓存,从而提高性能。
HTTP缓存有两种实现方式:强制缓存、协商缓存
2. 强制缓存
只要浏览器判断缓存没有过期,就直接使用本地缓存。

强制缓存是使用Cache-Control(相对时间)、Expires(绝对时间)两个HTTP响应头字段实现的,表示资源在客户端缓存的有效期。(其中Cache-Control更加精细,也是更加建议使用的)。
Cache-Control实现强制缓存流程:
- 第一次请求访问后,服务器返回资源并在Response头部加上Cache-Control,设置了过期时间的大小。
- 再次请求访问时,先判断资源是否过期。未过期------使用缓存;已过期------重新请求服务器。
- 服务器收到请求后,会再次更新Response头部的Cache-Control。
3. 协商缓存
比如响应码304。这种通过服务器告知客户端是否可以使用缓存的方式被称为协商缓存。

协商缓存可以基于两种头部来实现。
第一种:请求头中的If-Modified-Since字段、响应头中的Last-Modified字段。
- Last-Modified:这个响应资源的最后修改时间;
- If-Modified-Since:当资源过期,响应头中有Last-Modified,则再次发起请求的时候带上Last-Modified的时间,服务器收到请求后发现有If-Modified-Since就与被请求资源的Last-Modified对比,判断是否有修改(有修改200 OK返回最新资源,无修改304读本地缓存)。
第二种:请求头中的If-None-Match字段、响应头中的ETag字段。
- Etag:唯一标识响应资源;
- If-None-Match:当资源过期,浏览器发现有Etag,则在再向服务器发送请求时,会将请求头If-None-Match设置为ETag的值。服务器收到请求后进行对比,后续依旧是304和200 OK响应码。
这两种方式一种是基于时间,一种是基于唯一标识,很明显,唯一标识更加可靠。同时两种方式时,ETag的优先级也会更高。


四. HTTP特性
1. HTTP(1.1)的优点
简单、灵活、易拓展、广泛应用、跨平台。
- 简单
基本报文的格式就是header+body,头部信息也是key-value简单文本的形式,易于理解。
- 灵活、易拓展
各类请求方法、URL/URI、状态码、头字段,都允许自定义和扩充。
应用层协议。
HTTPS就是在HTTP和TCP层之间增加了SSL/TLS安全传输层。
- 广泛应用、跨平台
2. HTTP(1.1)的缺点
双刃剑:无状态、明文传输
- 无状态
好处:服务器不会记忆HTTP状态,减轻了负担,把更多的性能用来对外服务。
坏处:完成关联性操作时很麻烦(比如在购物的登录-加购-下单-结算-支付,都需要询问一遍身份信息)。
解决方案:Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态(类似于一个小纸条)。
- 明文传输
通过浏览器和Wireshark抓包都可以直接查看传输的信息,方便调试,但同时信息容易被窃取。
- 总言:不安全
使用明文(不加密,相关数据和信息容易泄露),不验证通信方的身份(可能进入假网站),无法验证报文完整性(网页上广告的植入)。
解决方案:HTTPS,也就是引入SSL/TLS层,提高了安全性。
3. HTTP(1.1)的性能如何?
HTTP基于TCP/IP,使用**"请求-应答"**的通信模式,其性能也与此有关。
- 长连接(持久连接)
HTTP/1.0性能上的问题,就是每发起一个请求,都需要三次握手,做了很多无谓的TCP连接的建立和断开。
而长连接(持久连接)的通信方式,特点是只要任意一段没有明确提出断开连接,则保持TCP连接状态(当然,超过一定时长还是会断开)。
- 管道网络传输
长连接的使用,使管道(pipeline)网络传输成为了可能。在同一个TCP连接里,客户端可以发起多个请求,当一个请求发起了,不必等待响应,就可以发送第二个请求。
但是服务器必须按照接收的顺序来响应这些请求。所以可能会出现响应队头阻塞的问题:
客户端发送两条请求,先A后B;服务器接收时是先B后A,那么就会先响应B后响应A。但此时,如果响应B需要很长时间,请求A的响应就会被阻塞。
HTTP/1.1管道解决了请求的队头阻塞,但是没解决响应的队头阻塞。
而请求队头阻塞,会在非持久连接中出现(TCP连接迟迟不断开,没法创建另一个新的连接)。
五.HTTP和HTTPS
1. HTTP与HTTPS的区别
-
HTTP明文传输,而HTTPS引入了SSL/TLS安全协议,使报文能加密传输。
-
HTTPS在TCP三次握手后,还需要进行SSL/TLS的握手过程,才可以进入加密报文传输。
-
HTTP端口号80,HTTPS端口号443。
-
HTTPS协议需要向申请数字证书,来保证服务器身份是可信的。
2. HTTPS解决了哪些HTTP的问题?
HTTP明文传输,容易被窃听、篡改、仿冒。而HTTPS引入SSL/TLS协议。

而SSL/TLS主要做了以下:
-
信息加密:交互信息无法窃取。
-
校验机制:无法串改通信内容,篡改了就不能正常显示。
-
身份证书:需要向证书机构申请证书保证服务器身份可信。
这又需要提到三个关键词:
- 混合加密:采用对称加密和非对称加密结合,实现信息机密性。
· 通信建立前,采用非对称加密交换"会话密钥",后续就不再使用非对称加密(非对称加密使用公钥和私钥,公钥可以随意分发,但私钥保密,解决了密钥交换的问题,但速度慢)。
· 通信过程中,使用对称加密的"会话密钥"加密明文数据(只是用一个密钥,必须保密,所以就无法安全地交换)。
- 摘要算法:生成"指纹验证"(唯一的),用于校验数据的完整性,解决了篡改的问题。
**·**客户端发送"明文+摘要",服务器接收后对比。
- 数字证书:服务器把自己的公钥注册到数字证书机构(CA),客户端使用公钥验证证书的真实性。
3. HTTPS是如何建立连接的
SSL/TLS协议基本流程:
-
客户端索要并验证服务器的公钥。
-
双方协商产生"会话密钥"。
-
双方使用"会话密钥"进行加密通信。
前两步也就是TLS的握手阶段(建立SSL/TLS),涉及四次通信。

SSL/TLS建立的详细流程:
- ClientHello
客户端发起加密通信请求,发送:
(1)客户端支持的SSL/TLS协议版本号,如TLS1.2。
(2)生成随机数,后面用于生成"会话密钥"。
(3)客户端支持的密码套件列表,如RSA加密算法。
- ServerHello
服务器响应,回应:
(1)确认SSL/TLS版本号,如果不支持,就关闭加密通信。
(2)服务器生成随机数,也是后面用来生成"会话密钥"的条件。
(3)确认密码套件列表。
(4)服务器的数字证书。
- 客户端回应
收到服务器的回应后,首先验证CA公钥,确定数字证书的真实性。没有问题,则:
(1)一个随机数,会被服务器公钥加密。
(2)加密通信算法改变通知,后面将通过"会话密钥"加密通信。
(3)客户端握手结束通知,把所有此前所有数据做个摘要,给服务器校验。
此时,服务器和客户端有了三个随机数(Client Random、Server Random、pre-master key),接着就用加密算法生成各自本次通信的"会话密钥"。
- 服务器的最后回应
生成"会话密钥"后,发送:
(1)加密通信算法改变通知。
(2)服务器握手结束通知,把此前所有的数据做个摘要,给客户端校验。
接下来,就是使用"会话密钥"的加密HTTP通信过程了。
六.HTTP的演变
1. HTTP/1.1相比HTTP/1.0的性能提高
性能改进:长连接减小了开销,管道网络传输减小整体响应时间。
性能瓶颈:
(1)请求/响应头部未经压缩就发送,头部信息越多延迟就越大。只能压缩body部分。
(2)每次发送相同的头部造成浪费。
(3)响应队头阻塞问题。
(4)没有请求优先级控制。
(5)请求只能客户端开始,服务器只能被动响应。
2. HTTP/2做的优化
HTTP/2是基于HTTPS的,有安全性上的保障。
性能改进:
-
头部压缩:如果请求头部是一样的或相似的,协议会消除重复的部分。使用HPACK算法------服务器客户端共同维护一张头信息表,所有字段带上索引,以后就只发索引号了。
-
二进制格式:不同于HTTP/1.1中纯文本形式的报文,全面采用二进制格式,头信息和数据体都是二进制,并统称为帧(头信息帧、数据帧)。虽然对人不友好,但是对计算机传输和解析很友好(比如状态码200 OK,HTTP/1.1表示为110010 110000 110000,HTTP/2表示为11001000)。
-
数据流:HTTP/2中每个请求或响应的所有数据包,称为一个数据流,数据流有唯一的StreamID(客户端奇数号,服务器偶数号),不同Stream的帧是可以乱序发送的(因此可以并发) ,通过StreamID组装。客户端还可以指定数据流的优先级。
-
多路复用:一个连接可以并发多个请求或回应,不用按照顺序。移除了HTTP/1.1中串行请求,不会再出现"响应队头阻塞",提高了连接的利用率。
-
服务器推送:改善了传统的"请求-应答"模式,服务器也可以主动发送消息(比如下图)。

性能缺陷:
Stream的并发,解决了HTTP层面上的"队头阻塞"问题,但是在TCP这一层,如果有丢包,就会触发"丢包重传"(因为内核中的TCP数据不是连续的,后续的HTTP请求都必须等待这个丢了的包重传回来),然后就会发生"队头阻塞"。
3. HTTP/3做的优化
为了解决HTTP/1.1和HTTP/2的问题,HTTP/3换用了UDP协议,用基于UDP的QUIC协议实现了类似于TCP的可靠传输。
QUIC的3个特点:
- 无队头阻塞
QUIC也有类似HTTP/2的多路复用,但是QUIC连接上的多个Stream之间没有依赖,都是独立的,某个流发生丢包了,只会阻塞这个流,其他流不受影响。

- 更快的连接建立
对于HTTP/1和HTTP/2,TCP和TLS是分层的,分别属于内核实现的传输层、openssl库实现的表示层,所以要分批握手。
HTTP/3的QUIC协议内部包含了TLS,握手的目的是为了确认双方的"连接ID",在它自己的帧会携带TLS里的"记录",仅需1个RTT就可以同时完成建立连接和密钥协商,甚至在第二次连接的时候,数据包和QUIC握手信息可以一起发送(0RTT)。
- 连接迁移
基于TCP的HTTP协议,由于是通过**四元组(源IP、源端口、目的IP、目的端口)**确定一条TCP连接,IP改变(比如当设备的网络从5G切换到WIFI时),那么必须断开连接,然后重新建立连接。重新三握四挥的连接迁移成本是很高的。
而QUIC是通过连接ID来标记通信的两端,即使IP变化,只要保留TLS密钥、连接ID,就可以无缝复用原连接,达到了连接迁移的功能。
所以QUIC是一个在UDP之上的伪TCP+TLS+HTTP/2的多路复用协议。