计算机网络是面试必考的内容之一,本篇为大家整理关于HTTP的几道面试题。
⭐码字不易,求个关注⭐
⭐点个收藏不迷路哦~⭐
你的支持是我持续学习的动力~
HTTP是超文本传输协议,也就是HyperText Transfer Protocol。
具体来说,HTTP协议是在计算机网络中的两点之间传输超文本的一种约定和规范。
Keep-Alive
。2xx
类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。
「 200 OK」是最常见的成功状态码,表示一切正常。
「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但没有返回实体内容。
「206 Partial Content」该状态码表示客户端进行了范围请求,而服务器成功执行了部分的GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
3xx
类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。
「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
「302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location
,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
「304 Not Modified」协商缓存时,该状态码表示资源未被修改,客户端可以继续使用缓存资源,用于缓存控制。
4xx
类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
「400 Bad Request」表示客户端请求报文中有语法错误。
「401 Unauthorized」该状态码表示客户端发送的请求需要有通过 HTTP 认证的认证信息(可能服务器会发送一个基于表单的认证信息,来确认用户身份)。另外若之前已进行过 1 次请求,则表示用户认证失败。
「403 Forbidden」表示服务器禁止访问资源,比如未获得文件系统的访问授权,访问权限出了问题。
「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
「405」自己手写Servlet时遇到,请求方法不匹配。访问浏览器默认是get方法。如果Servlet写的是doPost方法,就会报错。
5xx
类状态码表示服务器处理时内部发生了错误,属于服务器端的错误码。
「500 Internal Server Error」该状态码表明服务器端在执行请求时发生了错误。也有可能是 Web应用存在的 bug 或某些临时的故障。
「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
GET 的语义是请求获取指定的资源。GET 请求的参数位置一般是写在 URL 中。
POST 的语义是向指定的资源提交处理的数据,比如表单的add操作,需要在表单中指明使用post方法。Post通过表单提交,不会显示在URL上。
- 「安全」是指请求方法不会修改服务器上的资源。
- 「幂等」是指多次执行相同的操作,结果都是「相同」的。
使用缓存,可以避免重复发送HTTP请求。主要有两种实现方式,分别是强制缓存和协商缓存。
强制缓存
定义:只要浏览器的缓存资源没有过期,就直接使用浏览器的本地缓存。不会访问服务器。是否使用缓存由浏览器这边控制。
要实现强制缓存的话,是利用两个字段实现的:
Cache-control
和Expires
如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话,Cache-Control的优先级高于 Expires 。建议使用Cache-Control 来实现强缓存。
浏览器如何判断是否使用缓存?
- 浏览器第一次请求服务器资源时,服务器会在返回资源的同时,在响应头加上Cache-control设置过期时间大小。
- 浏览器再次请求服务器中的该资源时,会先比较请求资源的时间和Cache-Control 中的过期时间的大小,计算是否过期,如果没有,则使用该缓存,否则进行协商缓存。
- 服务器收到请求后,会再次更新响应头的Cache-Control。
HTTP状态码:
- 200 (form memory cache) : 不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
- 200( from disk cache): 不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
协商缓存
当浏览器本地的缓存过期,浏览器就会向服务器发送请求,之后由服务器告知客户端是否可以使用缓存【304(继续使用本地缓存)/200(更新缓存)】,这种方式就是协商缓存。通过协商结果来判断是否使用本地缓存。
协商缓存的两种头部实现方式
If-Modified-Since
和响应头部的Last-Modified
If-None-Match
和响应头部中的Etag
字段。
第一种头部实现的具体方式 ?
当本地资源过期了,发现响应中出现
Last-Modified
,那么第二次请求就会带上这个时间,服务器把last-Modified
和If-Modified-Since
两个时间进行对比,如果最后修改的时间(last-Modified
)比较新,就返回最新的资源。否则就返回状态码304,继续使用本地缓存。
第二种头部实现的具体方式?
当本地资源过期时,发现响应中出现
Etag
,那么第二次向服务器发送请求时,会将请求头If-None-Match
设置为Etag
的值。服务器收到请求后进行对比,资源没有变化则返回304,如果变化,则返回新的资源和状态码200。
同时有
Etag
和Last-Modified
?Etag的优先级更高,因为Etag能解决Last-Modified难以解决的问题。
- 文件没变,但是有可能最后修改时间改变了·。
If-Modified-Since
检查的粒度是秒级的,如果文件在1秒以内进行修改,无法使用。- 服务器可能并不能准确获取文件的最后修改时间。
最后注意:协商缓存都必须配合强制缓存中的Cache-control来使用,只有不能使用强制缓存时,才可以用协商缓存。
HTTP最突出的优点是:简单、灵活和易于拓展、应用广泛和跨平台。
简单
报文格式就是请求行、请求头、请求体。头部信息也是key-value
的文本形式,易于理解。
灵活和易于扩展
灵活:各种请求方法、URL、头部字段都没有固定,开发人员可以自定义。
易于扩展:HTTP工作在应用层,它的下层可以随意变化,比如HTTPS就是在HTTP与TCP层之间增加SSL/TLS安全传输层。(注:TLS(传输层安全)是更为安全的升级版 SSL。由于 SSL 这一术语更为常用,因此我们仍然将我们的安全证书称作 SSL。)
应用广泛
应用领域:从简单的Web网页,各种浏览器或者APP等,处处都在用HTTP。
开发领域:不限定编程语言或者操作系统,具有跨语言,跨平台的优越性。
缺点/优点:无状态
无状态的坏处:完成有关联性的操作时会很麻烦,比如用户从登录到下单支付的一系列操作,如果是无状态请求,用户的每一次操作都需要验证身份。
无状态的好处:不需要额外的资源记录状态信息,减轻服务器端压力。
缺点:不安全
Cookie技术:
现在可以使用Cookie技术来解决HTTP无状态的问题。
第一次客户端发送没有Cookie的信息,服务器就生产一个Cookie,在响应中返回。第二次客户端发送的请求就会带上Cookie。服务器进行检查Cookie,确认身份,之后进行响应。
长连接
HTTP/1.1实现了长链接,不需要每次请求都重新建立和断开TCP连接。减轻了服务器端的压力。性能得到一个提升。
管线化网络传输
也就是同一个TCP连接中,发出一个HTTP请求,可以不用等待服务器做出响应,直接发送另一个请求。也是可以提高性能。
但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应。
队头阻塞
如果某一个请求处理的耗时较长,就会出现队头阻塞。后面的所有请求都不能进行响应。HTTP/1.1只解决了请求的队头阻塞,没有解决响应的队头阻塞。
需要注意的是,HTTP/1.1的性能一般,HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。
保证了信息的机密性
HTTPS采用混合加密的方式实现信息的机密性。
使用非对称加密的方式来交换[会话密钥]。在通信过程中使用对称加密的形式来加密明文数据。
这样做的原因?
对称加密共同使用一个密钥。运算速度快。但是必须确保密钥的保密性。
非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发,私钥保密,解决了密钥交换问题。但是速度比较慢。
保证传输内容完整性,防止被篡改
使用摘要算法计算出内容的哈希值,再使用数字签名算法,对哈希值进行加密。
摘要算法+数字签名技术:
- A把消息用哈希函数处理生成消息摘要,并用私钥进行加密生成签名,把签名和摘要一起发送给B。
- B接收到数据后,采用相同的哈希函数生成消息摘要,并将接收的签名用配对的公钥解密,如果生成的摘要和解密的数字签名相同,说明签名验证成功。
SSL协议的基本流程:
客户端向服务器发起加密通信请求,ClientHello
请求。
主要发送
Client Random
),作为会话密钥的条件之一服务器收到请求后,向客户端发出响应,SeverHello
请求。
主要发送
Server Random
),作为会话密钥的条件之一客户端进行回应,首先验证服务器的数字证书的真实性。取出数字证书中服务器的公钥,然后使用它加密报文发送信息。
pre-master key
)。该随机数被服务器公钥加密。服务器端收到第三个随机数后,通过协商的加密算法,计算通信的会话密钥,发送最后的信息。
TLS协议在实现上分为握手协议和记录协议两层:
握手协议即之前的四次握手过程,负责协商加密算法,生产会话密钥,后序使用该密钥来保护应用程序数据。
记录协议即负责保护应用数据的完整性和来源。
具体过程如下:
消息认证码与消息摘要类似,区别是消息摘要算法只是对数据作摘要计算,而消息认证码涉及到加密过程。
新的方案选择先加密再 MAC,这种替代方案中,首先对明文进行填充和加密,再将结果交给 MAC 算法。这可以保证主动网络攻击者不能操纵任何加密数据。
这个问题的场景如下:客户端通过浏览器向服务器段发起HTTPS请求时,被假基站转发到了一个中间人服务器,于是客户端是和中间人服务器完成了TLS握手,然后这个中间人服务器再与真正的服务器完成TLS握手。
具体过程如下:
- 客户端向服务端发起 HTTPS 建立连接请求时,然后被「假基站」转发到了一个「中间人服务器」,接着中间人向服务端发起 HTTPS 建立连接请求,此时客户端与中间人进行 TLS 握手,中间人与服务端进行 TLS 握手;
- 在客户端与中间人进行 TLS 握手过程中,中间人会发送自己的公钥证书给客户端,客户端验证证书的真伪,然后从证书拿到公钥,并生成一个随机数,用公钥加密随机数发送给中间人,中间人使用私钥解密,得到随机数,此时双方都有随机数,然后通过算法生成对称加密密钥(A),后续客户端与中间人通信就用这个对称加密密钥来加密数据了。
- 在中间人与服务端进行 TLS 握手过程中,服务端会发送从 CA 机构签发的公钥证书给中间人,从证书拿到公钥,并生成一个随机数,用公钥加密随机数发送给服务端,服务端使用私钥解密,得到随机数,此时双方都有随机数,然后通过算法生成对称加密密钥(B),后续中间人与服务端通信就用这个对称加密密钥来加密数据了。
- 后续的通信过程中,中间人用对称加密密钥(A)解密客户端的 HTTPS 请求的数据,然后用对称加密密钥(B)加密 HTTPS 请求后,转发给服务端,接着服务端发送 HTTPS 响应数据给中间人,中间人用对称加密密钥(B)解密 HTTPS 响应数据,然后再用对称加密密钥(A)加密后,转发给客户端。
要发生这种场景的关键前提是用户点击接受了中间人服务器的证书。这个证书能够被浏览器识别出是非法的,于是就会提醒用户该证书存在问题。如果用户执意继续浏览网站,相当于接受了中间人伪造的证书,那么后续的HTTPS通信都能够被中间人监听了。
所以,HTTTPS协议本身到目前为止还是没有任何漏洞的,即使成功进行中间人攻击,本质上是利用了客户端的漏洞(用户执意继续访问),并不是HTTPS不够安全。
HTTP/1.1的性能瓶颈:
请求/响应头部未经压缩就发送,首部信息越多延迟就越大,只能压缩主体部分。【HTTP/2解决】
请求只能从客户端开始,服务器端接收。【HTTP/2解决】
会造成队头阻塞【HTTP/3彻底解决了队头阻塞问题】
头部压缩
HTTP/2会压缩请求头,如果多个请求头是一样的或者相似的,会消除重复的部分。
使用了HPACK算法,在客户端和服务器同时维护头信息表,将字段存入信息表中,生成索引号,以后只发送索引号即可。
二进制格式
HTTP/2全面采用二进制格式,头部信息和数据体都是二进制,并且统称为帧:头部帧和数据帧。
收到报文后,无需将明文转为二进制,而是直接解析二进制报文即可。增加了数据传输的效率。
并发传输
HTTP/2引入了Stream的概念,多个Stream复用在同一条TCP的连接上。
不同的HTTP请求,都有独一无二的StreamID,接收端可以通过StreamID来组装HTTP消息。
不同的Stream的帧可以乱序发送,所以HTTP/2可以并行交错的发送请求和响应。
一个TCP连接中包含多个Stream,Stream里可以包含多个Message,Message就对应HTTP/1中的请求和响应。Message里可以包含一条或多个Frame(帧)。
服务器推送
服务器不再被动的响应,而是可以主动地向客户端发送消息。
主要是因为客户端和服务端都可以建立Stream,StreamID也做了区分,客户端的StreamID必须是奇数,而服务器建立的StreamID必须是偶数号。
HTTP/3将TCP协议改为了UDP协议。UDP协议不管顺序,也不管丢包。
无队头阻塞
基于UDP的QUIC协议实现了类似TCP的可靠传输。当某个流发生丢包时,只会阻塞这个流,其他流不会收到影响,因此不存在队头阻塞的问题。
更快建立连接
HTTP/1和HTTP/2协议,TCP和TLS是分层的,难以合并在一起,需要分批次来握手。
但是HTTP/3的QUIC协议内部包含了TLS。会在发送帧的同时携带TLS的记录,再加上QUIC使用的是TLS/1.3,仅需一个RTT就可以同时完成建立连接与密钥协商。
连接迁移
QUIC 协议没有用TCP四元组的方式来“绑定”连接,而是通过连接 ID来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。
TCP四元组:
基于TCP传输协议的HTTP协议,都是通过四元组(源IP、源端口、目的IP、目的端口)来确定一条TCP连接的。