HTTP 面试
HTTP 有哪些方法,具体作用是什么
方法
- HTTP1.0:GET,POST 和 HEAD
- HTTP1.1:新增 OPTIONS,PUT,DELETE,TRACE 和 CONNECT(PATCH 见 rfc5789)
作用
- GET:用于请求服务器发送某些资源
- HEAD:请求资源的头部信息,并且这些头部与 HTTP GET 方法请求时返回的一致,该请求方法的一个使用场景是在下载一个大文件前先获取其大小再决定是否要下载,以此可以节约带宽资源
- OPTIONS:用于获取目的资源所支持的通信选项
- POST:发送数据给服务器
- PUT:用于新增资源或者使用请求中的有效负载替换目标资源的表现形式
- DELETE:用于删除指定的资源
- PATCH:用于对资源进行部分修改
- CONNECT:HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器
- TRACE:回显服务求收到的请求,主要用于测试或诊断
GET 和 POST 有什么区别
- 数据传输方式不同:GET 请求通过 URL 传输数据,而 POST 的数据通过请求体传输
- 安全性不同:POST 的数据因为在请求主体内,所以有一定的安全性保证,而 GET 的数据在 URL 中,通过历史记录,缓存的内容很容易查到数据信息
- 数据类型不同:GET 只允许 ASCII 字符,而 POST 无限制
- GET无害:刷新、后退等浏览器操作 GET 请求时无害的,POST 可能重复提交表单
- 特性不同:GET 是安全(指只读特性,该方法不会引起服务器状态变化)且幂等(指同一个请求方法执行多次和仅执行一次的效果完全相同),而 POST 是非安全非幂等的
PUT 和 POST 都是给服务器发送新增资源,有什么区别
- PUT 方法是幂等的:连续调用一次或者多次的效果相同(无副作用),而 POST 方法是非幂等的
- 通常,PUT 的 URI 指向是具体单一的资源,而 POST 可以指向资源的集合
- 如 新建文章 往往 POST,非幂等;而修改文章则 PUT 幂等
PUT 和 PATCH 都是给服务器发送修改资源,有什么区别
PUT 和 PATCH 都是更新资源,而 PATCH 用来对已知资源进行局部更新。如果发送修改信息是全量覆盖就是用 PUT, 如果只是部分修改则使用 PATCH。
http 的请求报文是什么样的
请求报文组成
- 请求行(请求方法字段、URL 字段、HTTP 协议版本字段。使用空格分隔,如 GET /index.hmtl HTTP/1.1)
请求头部(由关键字/值对组成,每行一对,关键字和值用 ‘:’ 分隔)
- User-Agent: 产生请求的浏览器类型
- Accept:客户端可识别的内容类型列表
- Host:请求的主机名,允许多个域名同处于一个 IP 地址,即虚拟主机
- 空行
- 请求体(POST PUT 等请求携带的数据)
HTTP 响应报文是什么样的
响应报文组成
- 响应行(由协议版本,状态码和状态码的原因短语组成,如 HTTP/1.1 200 OK)
- 响应头(响应部首组成)
- 空行
- 响应体(服务器响应的数据)
HTTP 响应部首有哪些
通用首部字段(General Header Fields):请求报文和响应报文两方都会使用的首部
- Cache-Control 控制缓存
- Connection 连接管理、逐条首部
- Upgrade 升级为其他协议
- via 代理服务器的相关信息
- Warning 错误和警告通知
- Transfor-Encoding 报文主体的传输编码格式
- Trailer 报文末端的首部一览
- Pragma 报文指令
- Date 创建报文的日期
请求首部字段(Request Header Fields):客户端向服务器发送请求的报文时使用的首部
- Accept 客户端或者代理能够处理的媒体类型
- Accept-Encoding 优先可处理的编码格式
- Accept-Language 优先可处理的自然语言
- Accept-Charset 优先可处理的字符集
- If-Match 比较实体标记(ETage)
- If-None-Match 比较实体标记(ETage)与 If-Match 相反
- If-Modified-Since 比较资源更新时间(Last-Modified)
- If-Unmodified-Since 比较资源更新时间(Last-Modified),与 If-Modified-Since 相反
- If-Ranges 资源未更新时发送实体 byte 的范围请求
- Range 实体的字节范围请求
- Authorization web 的认证信息
- Proxy-Authorization 代理服务器要求 web 认证信息
- Host 请求资源所在服务器
- From 用户的邮箱地址
- User-Agent 客户端程序信息
- Max-ForWards 最大的逐跳次数
- TE 传输编码的优先级
- Referer 请求原始放的 url
- Expect 期待服务器的特定行为
响应首部字段(Response Header Fields): 从服务器向客户端响应时使用的字段
- Accept-Ranges 能接受的字节范围
- Age 推算资源创建经过时间
- Location 令客户端重定向的 URI
- vary 代理服务器的缓存信息
- ETag 能够表示资源唯一资源的字符串
- WWW-Authenticated 代理服务器要求客户端的验证信息
- Server 服务器的信息
- Retry-After 和状态码 503 一起使用的首部字段,表示下次请求服务器的时间
实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用使用首部
- Allow 资源科支持 http 请求的方法
- Content-Language 实体的资源语言
- Content-Encoding 实体的编码格式
- Content-Length 实体的大小(字节)
- Content-Type 实体媒体类型
- Content-MD5 实体报文的摘要
- Content-Location 代替资源的 URI
- Content-Ranges 实体主体的位置返回
- Last-Modified 资源最后修改时间
- Expires 实体主体的国企时间
HTTP 状态码有哪些
2XX 成功
- 200 OK 客户端发来的请求在服务器端被正确处理
- 201 Created 请求已经被实现,而且有一个新的资源已经依据请求的需要而建立
- 202 Accepted 请求已接受,但是还没执行,不保证完成请求
- 204 No Content 请求成功,但响应报文不含实体的主体部分
- 206 Partial Content 进行范围请求
3XX 重定向
- 301 moved permanently 永久重定向,表示资源已被分配了新的 URL
- 302 found 临时性重定向,表示资源临时被分配了新的 URL
- 303 see other 表示资源存在着另一个 URL,应使用 GET 方法定向获取资源
- 304 not modified 表示服务器允许访问资源,但因发生请求未满足条件的情况
- 307 temporay redirect 临时重定向,和 302 含义相同
4XX 客户端错误
- 400 bad request 请求报文存在语法错误
- 401 unauthorized 表示发送的请求需要有通过 HTTP 认证的认证信息
- 403 forbidden 表示对请求资源的访问被服务器拒绝
- 404 not found 表示在服务器上没有找到请求的资源
- 408 Request Timeout 客户端请求超时
- 409 Conflict 请求的资源可能引起冲突
5XX 服务器错误
- 500 internal server error 表示服务器端在执行请求时发生了错误
- 501 Not Implemented 请求超出服务器能力范围,例如服务器不支持当前请求所需要的某个功能,或请求时服务器不支持的某个方法
- 503 service unavailable 表明服务器暂时处于超负载或正在停机维护,无法处理请求
- 505 http version not supported 服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本
重定向中 307,303 和 302 的区别
302 是 http 1.0 的协议状态码,在 http 1.1 版本的时候为了细化 302 状态码又新增 303 和 307。
- 303 明确表示客户端应当采用 get 方法获取资源,会把 POST 请求变为 GET 请求进行重定向
- 307 会遵照浏览器标准,不会从 POST 变为 GET
HTTP 的 keep-alive 作用是什么
在早期的 HTTP/1.0 中,每次 HTTP 请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重用连接。后来的 HTTP/1.0 以及 HTTP/1.1 中,引入了重用连接的机制,就是在 http 请求头中加入 Connection:keep-alive 来告诉对方这个请求响应完后不要关闭,下次可以继续使用。协议规定 HTTP/1.0 如果想要保持长连接,需要在请求头中加上 Connection: keep-alive
优点:
- 较少的 CPU 和内存的使用(由于同时打开的连接数减少了)
- 允许请求和应答的 HTTP 管线化
- 降低拥塞控制(TCP 连接减少了)
- 减少了后续请求的延迟(无需再进行握手)
- 报告错误无需关闭 TCP 连接
HTTPS 的作用
HTTPS 是安全版的 HTTP,因为 HTTP 协议的数据是明文进行传输的,所以对于一些敏感信息的传输就很不安全,HTTPS 目的就是解决 HTTP 的安全问题出现的。
HTTPS 是如何保证安全的
对称加密:即通信双方都是用同一个密钥进行加解密。对称加密虽然简单性能也好,但是无法解决首次把密钥发给对方的问题,很容易被拦截密钥。
非对称加密:
- 私钥 + 公钥 = 密钥对
- 用私钥加密的数据,只有对应的公钥才能解密,用公钥加密的数据,只有对应的私钥才能解密
- 因为通信双方的手里都有一套自己的密钥对,通信之前双方会先把自己的公钥都先发给对方
- 然后对方再拿着这个公钥来加密数据响应给对方,等到到了对方那里,对方再用自己的私钥进行解密
非对称加密虽然安全性更高,但是带来的问题就是速度很慢,影像性能
- 解决方案
结合两种加密方式,将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方使用对称加密来进行沟通。
但是会引入新的问题,中间人问题:
如果此时在客户端和服务器端存在一个中间人,这个中间人只需要把原本双方通信互发的公钥,换成自己的公钥,这样中间人就可以轻松解密通信双方所发送的所有数据。
所以此时需要一个安全的第三方颁发证书(CA),证明身份防止被中间人攻击
证书包括:签发者、证书用途、使用者公钥、使用者私钥、使用者的 HASH 算法、证书到期时间等
但是,如果中间人篡改了证书,那么身份证明就无效了,此时需要一个新的技术——数字签名。
数字签名,就是用 CA 自带的 HASH 算法对证书的内容进行 HASH 得到一个摘要,再用 CA 的私钥加密,最终组成数字签名。
当别人把证书发过来的时候,再用同样的 Hash 算法,再次生成消息摘要,然后用 CA 的公钥对数字签名解密,得到 CA 创建的消息摘要,两者进行比较,就知道中间有没有人被篡改了。
HTTP2 相对于 HTTP1.x 有什么优势和特点
二进制分帧
- 帧:HTTP/2 数据通信的最小单位消息,指 HTTP/2 中逻辑上的 HTTP 消息,如请求和响应等,消息由一个或多个帧组成
- 流:存在于连接中的一个虚拟通道,流可以承载双向消息,每个流都有一个唯一的整数 ID
- HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效
头部压缩
HTTP/1.x 会在请求和响应中重复地携带不常改变的、冗长的头部数据,给网络带来额外的负担- HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送
- 首部表在 HTTP/2 的连接存续期内始终存在,由客户端和服务器共同渐进地更新
- 每个新的首部键值对要么被追加到当前表的末尾,要么替换表中之前的值
可以理解为只发送差异数据,而不是全部发送,从而减少头部的信息量
服务器推送
- 服务端可以在发送页面 HTML 时主动推送其他资源,而不用等到浏览器解析到相应位置,发起请求再响应。如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 时再发送请求。
- 服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收。
- 主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。
多路复用
HTTP 1.x 中,如果想并发多个请求,必须使用多个 TCP 链接,且浏览器为了控制资源还会对单个域名有6-8个的 TCP 链接请求限制
HTTP2 中:- 同域名下所有通信都在单个连接上完成
- 单个连接可以承载任意数量的双向数据流
- 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以是乱序发送,可以根据首部的流标识可以重新组装
HTTP 的缓存的过程是怎样的?
步骤:
(1)客户端向服务器发出请求,请求资源
(2)服务器返回资源,并通过响应头决定缓存策略
(3)客户端根据响应头的决策决定是否缓存资源,并将响应头与资源缓存下来
(4)在客户端再次请求且命中资源的时候,此时客户端去检查上次缓存的缓存策略,根据策略的不同、是否过期等判断是直接读取本地缓存,还是与服务器协商缓存
什么时候回触发强缓存或者协商缓存
强缓存
强缓存离不开两个响应头 Expires 与 Cache-Control- Expires:HTTP1.0 提出的一个表示资源过期时间的 header,它描述的是一个绝对时间,由服务器返回,Expires 受限于本地时间,如果修改了本地时间,可能会导致缓存失效
Cache-Control:Cache-Control 出现于 HTTP/1.1,优先级高于 Expires,表示的是相对时间(如 Cache-Control: max-age=315360000)
其他配置- Cache-Control:public 可以被所有用户缓存,包括终端和 CDN 等中间代理服务器
- Cache-Control:private 只能被终端浏览器缓存,不允许中继缓存服务器进行缓存
- Cache-Control:no-cache,先缓存本地,但是在命中缓存之后必须与服务器验证缓存的新鲜度才能使用
- Cache-Control:no-store,不会产生任何缓存
在缓存有效期内命中缓存,浏览器会直接读取本地的缓存资源,当缓存过期之后会与服务器进行协商
- 协商缓存
当第一次请求时服务器返回的响应头中没有 Cache-Control 和 Expires 或者 Cache-Control 和 Expires 过期 或 其属性为 no-cache 时,那么浏览器第二次请求时就会与服务器进行协商
如果缓存和服务端资源的最新版本是一致的,那么就无需再次下载该资源,服务端直接返回 304 Not Modified 状态码,如果服务器发现浏览器中的缓存已经是旧版本了,那么服务器会把最新资源的完整内容返回给浏览器,状态码就是 200 OK
服务器判断缓存是否是新鲜的方法就是依靠 HTTP 的另外两组信息
- Last-Modified/If-Modified-Since
客户端首次请求资源时,服务器会把资源的最新修改时间 Last-Modified 通过响应首部发送给客户端,当再次发送请求时,客户端将服务器返回的修改时间放在请求头 If-Modified-Since 发送数据给服务器,服务器与服务器上的资源进行对比,如果服务器资源更新,那么就返回最新的资源,状态码为 200,当服务器资源与客户端请求首部资源一致,证明客户端的资源是最新的,返回 304 状态码,表示客户端直接用缓存即可 - ETag/If-None-Match
Etag 的流程和 Last-Modified 是类似的,区别就在于 ETag 是根据资源内容进行 Hash,生成一个信息摘要,只要资源内容有变化,这个摘要信息就会发生巨变,通过摘要信息比对,就能确定客户端的缓存资源是否为最新,比 Last-Modified 的精确度要更高