HTTP协议详解 加强
接口由黑马提供的教学接口 API 点击查看文档
大纲链接 §
[toc]
HTTP协议简介 ⇧
01. HTTP协议简介-什么是通信 ⇧
通信就是信息的传递和交换
- 通信三要素
- 主体
- 内容
- 方式
 
02. HTTP协议简介-什么是通信协议 ⇧
通信协议(
Communication Protocol)时值通信的双方完成通信所必须遵守的规则和约定
- 通俗地理解,通信双方采用约定好的格式来发送和接受消息,这种事先约定好的通信格式,就叫做通信协议
互联网中的通信协议
- 客户端与服务器之间要实现网页内容的传输,则通信的双方必须遵守网页内容的传输协议
- 网页内容又叫做超文本,因此网页内容的传输协议又叫做超文本传输协议(Hyper Text Transfer Protocol),简称HTTP协议
03. HTTP协议简介-什么是HTTP协议 ⇧
HTTP协议即超文本传输协议,它规定了客户端与服务器之间进行网页内容传输时,所必须遵守的格式
- 客户端要以HTTP协议要求的格式把数据提交到服务器
- 服务器要以HTTP协议要求的格式把内容响应给客户端
04. HTTP协议简介-HTTP协议的交互模型 ⇧
HTTP协议采用了 请求/响应 的交互模型
- 客户端发起 HTTP 请求
- 服务器返回 HTTP 响应
05. HTTP协议特性 ⇧
0.5.1 无连接
- HTTP协议限制每次连接 只处理一个请求
- 服务器处理完客户端的请求,并发出响应之后,立即 断开连接,以此节省传输时间
- 若想保持连接可设置字段:"Connection": "keep-alive",或使用WebSocket
0.5.2 无状态
- HTTP协议对 事务处理 没有记忆能力
- 后续处理如果需要先前的信息,则必须 重传,导致每次连接需要的数据量增大
- 若想保存状态可采用:Session、Cookie或JWT技术
HTTP报文/消息
- 用于HTTP协议交互的信息即为HTTP报文,分为 请求报文 和 响应报文
- 报文由「报文首部、空行、报文主体」构成
- 报文首部由「起始行(请求行/状态行)、首部字段」构成
- 请求报文首部由「请求行、首部字段」构成
- 请求报文的 起始行 称为 请求行
- 其包括「请求方法、请求URI、HTTP版本」
 
- 响应报文首部由「状态行、首部字段」构成
- 响应报文的 起始行 称为 状态行
- 其包括「HTTP版本、状态码、原因短语」
 
- 首部字段 分为:
- 通用首部字段:请求报文和响应报文都会用到的首部
- 请求首部字段
- 响应首部字段
- 实体首部字段:用于补充与实体相关的信息
- 其它:RFC中未定义的首部,如为 Cookie服务的首部字段 (Cookie、Set-Cookie)
 
- 空行用于分割 报文首部 与 报文主体
- 报文主体即具体数据,请求报文 对应 请求体,响应报文 对应 响应体
 
- 请求报文首部由「请求行、首部字段」构成
在命令行中使用
curl -v https://www.baidu.com发送请求,查看报文结构
HTTP请求消息 ⇧
01. HTTP请求消息-什么是HTTP请求消息 ⇧
- 由于HTTP协议属于客户端浏览器和服务器之间的通信协议
- 因此,客户端发起的请求叫做 HTTP请求
- 客户端发送到服务器的消息(报文),叫做 HTTP请求消息(报文)
02. HTTP请求消息-HTTP请求消息的 4个组成部分 ⇧
HTTP请求消息由 请求行(
request line或start-line)、请求头部(request headers)、空行、和 请求体(request body) 4个部分组成
03. HTTP请求消息-请求行 ⇧
- 请求行由 请求方式、URL 和 HTTP协议版本 3个部分组成
- 之间使用空格隔开
- 通过浏览器的 Network 面板,发起 AJAX 请求时,查看请求的 标头(Headers)选项卡中的请求头Request Headers
- 点击查看源 (View source)
浏览器打开任意网址控制台打开 Network 面板,点击 view source 查看源
- POST /api/post HTTP/1.1即请求行
- 并不是所有完整的 URL,是去掉 协议、域名和端口号、查询参数后的 URL
04. HTTP请求消息-请求头部 ⇧
- 请求头部用来描述 客户端基本信息,负责将客户端相关信息告知服务器
- 请求头部 包含不同的字段
- User-Agent用来说明当前是什么类型的客户端(浏览器)
- Content-Type用描述发送到服务器的 数据格式
- Accept用来描述客户端能够接收 返回内容的类型
- Accept-Language用来描述客户端期望接收那种人类语言的文本内容
 
- 请求头由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔
常见的请求头字段
| 头部字段 | 说明 | 
|---|---|
| HOST | 需要请求的服务器域名 | 
| Connection | 客户端与服务器的连接方式: close或者keep-alive | 
| Content-Length | 用来描述请求体的大小 | 
| Accept | 客户端可识别的响应内容类型列表 | 
| User-Agent | 产生请求的浏览器类型 | 
| Content-Type | 客户端告诉服务器实际发送的数据类型 | 
| Accept-Encoding | 客户端可接收的内容压缩编码形式 | 
| Accept-Language | 用户期望获得的自然语言的优先顺序 | 
05. HTTP请求消息-空行 ⇧
最后一个请求头字段的后面是一个空行,通知服务器 请求头部至此结束
- 请求消息中的空行,用来分隔 请求头部 和 请求体
06. HTTP请求消息-请求体 ⇧
请求体中存放,是要通过 POST等方式 (非GET方式)提交给服务器的数据
- GET 请求没有请求体,GET 请求到空行结束
HTTP响应消息 ⇧
响应消息就是 服务器响应给客户端的消息内容 ,也叫作响应报文,或者应答报文
01. HTTP响应消息-响应消息的概念以及组成部分 ⇧
HTTP响应消息由 状态行(
status line)、响应头部(response header)、空行、和 响应体(response body) 4个部分组成
02. HTTP响应消息-状态行 ⇧
- 状态行是由 HTTP协议版本、状态码 和 状态码描述 3个部分组成
- 之间使用空格隔开
03. HTTP响应消息-响应头部 ⇧
响应头部用来描述 服务器的基本信息
- 响应头部由多行 键/值对 组成
- 每行的键和值之间用英文的冒号分隔
常见的响应头字段
- 关于更多响应头字段的描述,可以查看 MDN 官方文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers
04. HTTP响应消息-空行 ⇧
- 在最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端 响应头部至此结束
- 响应消息中的空行,用来分隔 响应头部 和 响应体
05. HTTP响应消息-响应体 ⇧
- 响应体中存放的,是服务器响应给客户端的资源内容
HTTP请求方法 ⇧
HTTP 请求方法,属于 HTTP 协议中的一部分
请求方法的作用是:用来表明 对服务器上资源执行的操作
- 常用的请求方法是 GET和POST
区别有:(语义、缓存、编码、传参、幂等性)
- 从 语义 角度:GET用于获取资源,POST用于上传资源
- 从 缓存 角度:GET请求会被浏览器 主动缓存,POST不会;
- 从 编码 角度:GET必须对 URL 进行编码,POST无限制;
- 从 参数 角度:GET参数暴露 在URL中,仅接受ASCII字符;POST放在 请求体 中,且参数无限制,更适合传输敏感信息;
- 从 幂等性 角度:GET是幂等的,POST不是;
什么是幂等性?
- 在相同条件下,一次请求 和 重复多次 请求对资源的影响是一致的,则该操作 幂等
HTTP的主要请求方法
| 序号 | 方法 | 描述 | 
|---|---|---|
| 1 | GET | 查询 发送请求来获取服务器上的资源,请求体中不包含请求数据,请求数据放在请求头中 | 
| 2 | POST | 新增 向服务器提交数据(用户注册/表单/文件上传)数据包含在请求体中提交给服务器 | 
| 3 | PUT | 修改 向服务器提交资源,并使用提交的新数据替换掉服务器中对应的旧资源 | 
| 4 | DELETE | 删除 请求服务器删除指定的资源 | 
| 5 | HEAD | 请求一个与 GET请求 响应头部 相同的响应,无需响应体,不会返回所请求的实体数据,仅返回响应头;可用于确认资源是否存在或检查资源是否更新,超链接探测器很多都基于 HEAD 方法进行实现 | 
| 6 | OPTIONS | 获取目标服务器支持的请求方法,允许客户端查看服务器的性能、AJAX跨域时的预检等 | 
| 7 | CONNECT | 建立一个由目标资源标识的服务器的隧道 | 
| 8 | TRACE | 沿着到目标资源的路径执行一个消息环回测试, 主要用于测试或诊断 | 
| 9 | PATCH | 对 PUT 方法的补充,用来对已知资源进行局部更新 | 
浏览器为什么会自动发起 OPTIONS 请求
- 当发起 跨域请求 时,如果为 非简单请求,浏览器会自动触发 预检请求(即 OPTIONS 请求)
- OPTIONS请求 用于确认目标资源 是否支持跨域;若为简单请求,则不触发预检,正常请求
- 204 No Content MDN
也就是一旦触发预检,则发送两次请求,影响性能,可做如下优化:
- 同域则不触发
- 避免 OPTIONS 请求:上图为 POST 请求设置头部字段 Content-Type: application/json后的预检请求
- 可将其设置成 application/x-www-form-urlencoded| multipart/form-data | text/plain之一,来规避触发预检
- 设置请求头部字段: "Access-Control-Max-Age": 600,单位秒,一般设置为10分钟
PUT & DELETE
- PUT用于更新替换资源,- DELETE用于删除资源
- RESTful 风格会使用 PUT & DELETE;实际开发中大家可自行评估选用 PUT & DELETE 还是 POST
CONNECT
- 创建隧道,用于代理服务器
HTTP响应状态码 ⇧
01. HTTP响应状态码-什么是HTTP响应状态码 ⇧
HTTP 响应状态码(
HTTP Status Code),也属于 HTTP 协议的一部分,用来标识响应的状态
- 响应状态码会随着响应消息一起被发送至客户端浏览器
- 通过浏览器根据服务器返回的响应状态码,就能知道这次 HTTP 请求的结果是成功还是失败了
02. HTTP响应状态码-HTTP响应状态码的组成及分类 ⇧
- HTTP 状态码由三个十进制数字组成
- 第一个十进制数字定义了状态码的类型
- 后两个数字用来对状态码进行细分
 
- HTTP 状态码共分为 5 种类型
| 分类 | 分类描 | 
|---|---|
| 1** | 信息,服务器收到请求,需要请求者继续执行操作(实际开发中很少遇到 1** 类型的状态码) | 
| 2** | 成功,操作被成功接收并处理 | 
| 3** | 重定向,需要进一步的操作以完成请求 | 
| 4** | 客户端错误,请求包含语法错误或无法完成请求 | 
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 | 
- 完整的 HTTP 响应状态码,可以参考 MDN 官方文档 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
03. HTTP响应状态码-2xx成功相关的响应状态码  ⇧ 
2**范围的状态码,表示服务器已成功接收到请求并进行处理
- 常见的 2**类型的状态码如下:
| 状态码 | 状态码英文名称 | 中文描述 | 
|---|---|---|
| 200 | OK | 请求成功。一般用于 GET 与 POST 请求 | 
| 201 | Created | 已创建。成功请求并创建了新的资源,通常用于 POST 或 PUT 请求 | 
| 204 | No Content | 请求成功,但无内容返回 | 
| 206 |  Partial Content | 客户端进行范围请求,响应报文中返回由 Content-Range指定范围的实体内容 | 
04. HTTP响应状态码-3xx重定向相关的响应状态码  ⇧ 
3**范围的状态码,表示服务器要求客户端重定向,需要客户端进一步的操作以完成资源的请求
- 常见的 3**类型的状态码如下:
| 状态码 | 状态码英文名称 | 中文描述 | 
|---|---|---|
| 301 | Moved Permanently | 永久移动。请求的资源已被永久地移动到新的 URI,返回信息会包括新的 URI,浏览器会自动重定向到新的 URI。并标记今后任何新的请求都应使用新的 URI 代替;响应的 Location 头字段会提供资源现在的 URL。直接使用 GET 方法发起新情求。 | 
| 302 | Found | 临时移动。与 301 类似。但资源只是临时被移动。客户端只应该将 Location 返回的 URL当做临时资源来使用。直接使用 GET 方法发起新情求。客户端今后应继续使用原有 URI 请求资源 | 
| 304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源(响应消息中不包含响应体)。客户端通常会缓存访问过的资源,即可直接使用客户端未过期的缓存(资源未修改,表示本地缓存仍然可用) | 
补充
HTTP重定向相关
- 在 HTTP中,如果服务器返回了一个重定向响应进行重定向并且是以3开头的状态码,里面有一个Location头字段表示要重定向的位置。浏览器收到响应后会直接加载Location里指定的URL
- 状态码301和308都属于永久重定向,永久重定向意味着原始URL不再可用,替换成了一个新的内容。所以搜索引擎以及其他爬虫识别这两个状态码时,会更新旧 URL 的资源。
- 而 302/303/307都属于临时重定向
05. HTTP响应状态码-4xx客户端错误相关的响应状态码  ⇧ 
4**范围的状态码,表示客户端的请求有非法(不合语法)内容,从而导致请求失败
- 常见的 4**类型 的状态码如下:
| 状态码 | 状态码英文名称 | 中文描述 | 
|---|---|---|
| 400 | Bad Request | 1 语义有误。当前请求无法被服务器理解。除非进行修改,否则客户端不应重复提交这个请求;2 请求参数有误 | 
| 401 | Unauthorized | 未经授权认证。当前请求需要用行用户验证 | 
| 403 | Forbidden | 服务器已经理解请求,但是拒绝执行 | 
| 404 | Not Found | 服务器无法根据客户端的请求找到资源(通常是网页) | 
| 408 | Request Timeout | 请求超时。服务器等待客户端发送的请求时间过长,超时 | 
06. HTTP响应状态码-5xx服务端错误相关的响应状态码 ⇧
5**范围的状态码,表示服务器未能正常处理客户端的请求,而出现意外错误
- 常见的 5**类型的状态码如下:
| 状态码 | 状态码英文名称 | 中文描述 | 
|---|---|---|
| 500 | Internal Sever Error | 服务器内部错误,无法完成请求 | 
| 501 | Not Implemented | 未实现请求方法 。服务器不支持该请求方法,无法完成请求。 只有 GET 和 HEAD 这两种请求是要求每个服务器必须支持的,其它请求方法在不支持的服务器上会返回 501 | 
| 503 | Service Unavailable | 由于超载或系统维护,服务器暂时地无法处理客户端的请求 | 
可以一同记忆的状态码
| 状态码 | 状态码英文名称 | 中文描述 | 
|---|---|---|
| 206 | Partial Content | 部分内容。成功状态响应代码表示请求已成功,并且主体包含所请求的 数据区间,该数据区间是在请求的 Content-Range首部指定的 | 
| 416 | Range Not Satisfiable | 服务器无法处理所请求的 数据区间。所请求的数据区间不在文件范围之内,即 Content-Range首部的值,虽然从语法上来说是没问题的,但是从语义上来说却没有意义 | 
其他HTTP相关知识点的有:HTTP缓存、HTTP状态管理、HTTP内容协商、HTTP持久连接机制、代理-网关-隧道、HTTP范围请求、HTTPS相关
HTTP缓存
强缓存 V.S 协商缓存
- 两者的区别在于:
- 是否需要向服务器 验证本地缓存 是否有效
- 强缓存 直接使用 本地缓存
- 协商缓存则需 与服务器进行协商 后,确定是否使用本地缓存
 
强缓存
- 响应头部字段中设置 Cache-Control: max-age=xxx,public
- 表示在xxx秒内再次访问该资源,均使用本地缓存
- public表示允许客户端及代理服务器(CDN)缓存
General中
- 命中缓存
-Status Code: 200 (from memory cache)-Status Code: 200 (from disk cache)
- 这里浏览器会自动分配存储到内存(memory cache)中还是磁盘(disk cache)中
存在的问题
- 感知不到资源更新,缓存不过期则不会重新获取
解决
- 缓存的意义在于减少请求,更多的使用本地资源,给用户更好的体验同时减轻服务器压力
- 所以最佳实践应尽可能命中强缓存,同时在更新资源时让客户端的缓存失效
- 在打包静态资源文件时,根据内容进行 hash 计算,以此来生成文件名
- 此时请求资源URL改变,浏览器重新加载资源
协商缓存
General中
- 命中缓存
-Status Code: 304 (Not Modified)
- 未命中缓存
-Status Code: 200 (OK)
Response Headers中的Last-Modified, 与Request Headers中的If-Modified-Since
- 文件时间戳对比
- 首次请求资源时,服务器返回的首部字段中会携带 Last-Modified- 值为 GMT 时间戳
 
- 当再次请求资源时,浏览器会自动带上 If-Modified-Since,该值与Last-Modified做对比- 若相同,则返回304,命中缓存
- 若不同则返回200,发送最新资源
 
存在的问题
- Last-Modified记录的是精确到秒的时间格式,若在 1s 内资源发生变化,则- Last-Modified感知不到,无法返回新资源
- 协商缓存最大的问题就是每次都要向服务器验证一下资源的有效性
Etag 与 If-None-Match 文件Hash值对比
- 首次请求资源时,服务器返回的首部字段中会携带 Etag
- 当再次请求资源时,浏览器会自动带上 If-None-Match,该值与Etag做对比
- 实体标识Etag与If-None-Match配对- 若相同,则返回304,命中缓存
- 若不同则返回200,则资源已更改,发送最新资源
 
Etag与If-None-Match优先级高于Last-Modified与If-Modified-Since
- 与 Last-Modified相比,Etag是根据文件内容生成的唯一标识
- 当文件变化,则 Etag变化
- 两者同时存在时,Etag优先级高于Last-Modified。
总结 ⇧
- 能够说出什么是HTTP协议
- 能够知道HTTP请求消息的组成部分
- 能够知道HTTP相应消息的组成部分
- 能够说出常见的请求方法
- 能够说出常见的响应状态码
参考文章
相关文章
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名
- 河 掘 思 知 简