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
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名
- 河 掘 思 知 简