网络2️⃣HTTP-报文
超文本传输协议(Hyper Text Transfer Protocol)
在计算机世界中的两点之间,传输文字、图片、音视频等超文本数据的约定和规范。
1、HTTP 报文
报文/消息(message):数据包在应用层的称呼。
具体分为 HTTP 请求报文和 HTTP 响应报文。
结构:
-
报文首部:请求报文和响应报文有所不同。
- 请求行(方法、URI 和 HTTP 版本)/状态行(HTTP 版本、状态码、原因短语)
- 首部字段
- 请求首部字段/响应首部字段
- 通用首部字段
- 实体首部字段
- 其它
-
空行:
CRLF
-
报文主体:应被发送的数据(实体主体)。
2、报文首部 🔥
2.1、请求行 - 方法
客户端指定 HTTP 版本,根据需要使用不同方法,向指定 URI 发出请求报文。
服务器会产生不同行为。
支持 版本 | 作用 | 含义 | |
---|---|---|---|
GET | ALL | 获取资源 |
请求资源是文本则直接返回,是 CGI 等程序则返回执行结果 |
POST | ALL | 传输实体主体 | |
PUT | ALL | 传输文件 | 在请求报文中包含文件内容,将文件保存到指定 URI |
HEAD | ALL | 获取报文首部 | 只获取报文首部,不获取报文主体 |
DELETE | ALL | 删除文件 | 与 PUT 相反,删除指定 URI 的资源 |
LINK | 1.0 | 建立和资源之间的连接 | |
UNLINE | 1.0 | 断开连接关系 | |
OPTIONS | 1.1 | 询问支持的方法 | 向服务器询问某个 URI 支持的请求方法 |
TRACE | 1.1 | 追踪路径 | 让服务器将请求通信环回给客户端 |
CONNECT | 1.1 | 使用隧道协议连接代理 | 在与代理服务器时建立隧道,用隧道协议进行 TCP 通信 |
2.1.1、GET & POST
GET | POST | |
---|---|---|
语义(RFC 规范) | 从服务器获取指定的资源(文本、页面、图片视频等) | 根据请求负荷(报文 body)对指定的资源做出处理,具体处理方式视资源类型而不同 |
位置 | 参数通常写在 URL 中 | 数据通常写在报文 body 中 |
格式要求 | URL 仅支持 ASCII,所以 GET 参数只能是 ASCII 字符 | body 数据可以是任意格式 |
浏览器限制 | 对 URL 长度限制 | 对 body 大小不做限制 |
示例
-
GET:打开一篇文章。
-
浏览器:发送 GET 请求给服务器。
-
服务器:响应文章的所有文字及资源。
-
-
POST:在文章提交留言。
-
浏览器:发送 POST 请求给服务器(留言内容放在报文 body 中)。
-
服务器:执行请求,返回处理结果。
-
2.1.2、安全 & 幂等
安全:在 HTTP 协议中,指请求方法不会破坏服务器上的资源。
幂等:多次执行相同的操作,结果相同。
根据 RFC 规范的语义,GET 和 POST 的安全幂等性如下。
- GET:安全、幂等
- 安全:GET 是只读操作,不影响服务器上的数据。
- 幂等:每次 GET 请求结果都是相同的。
- 可以对 GET 请求的数据做缓存
- 浏览器缓存:浏览器可以避免重新发请求,甚至可以将 GET 请求保存为书签。
- 代理缓存:如 Nginx
- POST:不安全、不幂等
- 不安全:POST 是新增或提交数据的操作,会修改服务器上的资源。
- 不幂等:多次 POST 会薪新增多个资源。
- 浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。
2.2、响应行 - 状态码
状态码:表示请求的响应结果。
状态码和原因短语一一对应,成对出现。
- | 类型 | 具体含义 |
---|---|---|
1xx | Informational (信息性) |
请求正在处理 |
2xx | Success (成功) |
请求正常处理完毕 |
3xx | Redirection (重定向) |
资源位置发生变动,需要客户端执行特殊操作 |
4xx | Client Error (客户端错误) |
请求报文有误,服务器无法处理 |
5xx | Server Error (服务端错误) |
服务器处理请求时,内部发生错误 |
1xx(实际用的比较少)
- 101 Switching Protocols:服务器通过 Upgrade 消息头,通知客户端采用不同的协议来完成这个请求。
2xx
- 200 OK:一切正常
- 204 No Content:不含报文 body
- 206 Partial Content:范围请求,用于 HTTP 分块下载或断点续传。
- 客户端使用
Range
首部字段,指定资源的 byte 范围。 - 服务端返回相应范围的数据,并响应状态码
206
。
- 客户端使用
3xx
-
301 Moved Permanently:永久重定向。
- 请求资源已不存在,需改用新 URL 再次访问。
-
302 Found:临时重定向。请求资源还在,但暂时需要用另一个 URL 来访问。
- 301 和 302 都会在响应首部中使用字段 Location,指明后续要跳转的 URL。
- 浏览器会自动重定向新的 URL。
-
303 See Other:资源存在另一个 URI,且需要按 GET 方式访问。
- 301 和 302 标准中禁止将 POST 方法改成 GET;303 标准中,应当用 GET 方式访问资源的另一个 URI。
- 浏览器遇到上述状态码时通常不遵守标准,将 POST 改成 GET 并重新发送请求。
- 307 会按照浏览器标准,不会从 POST 变成 GET。
-
304 Not Modified:资源未修改(aka. 缓存重定向)。
- 告诉客户端可以继续使用缓存,用于缓存控制。
-
307 Temporary Redirect:不从 POST 变成 GET 请求
4xx
- 400 Bad Request:请求报文中存在语法错误(比较笼统)
- 401 Unauthorized:请求未通过 HTTP 认证
- 403 Forbidden:服务器禁止访问(未获得授权、访问权限不足)
- 404 Not Found:请求资源在服务器上不存在或未找到
5xx
- 500 Internal Server Error:类似 400,比较笼统的错误码
- 501 Not Implemented:客户端请求的功能还不支持
- 502 Bad Gateway:服务器作为网关或代理时返回的错误码
- 表示服务器自身工作正常,访问后端服务器发生了错误。
- 503 Service Unavailable:服务器处于超载或停机维护
2.3、首部字段
首部字段:键值对的形式,用于传递额外的重要信息。
- 类型:根据是否使用缓存代理
- 端到端首部(End-to-end):会转发给最终接收目标,且必须保存在由缓存生成的响应中(缓存代理)。
- 逐跳首部(Hop-by-hop):单次转发有效,因经过缓存或代理后不再转发(非缓存代理)。
- 分类:
- 通用首部字段
- 请求首部字段、响应首部字段
- 实体首部字段
- 其它
2.3.1、通用首部字段
-
Connection
:常用于客户端要求服务器使用 HTTP 长连接机制,以便请求复用。-
HTTP 长连接:只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
-
HTTP/1.1 默认长连接。为了向后兼容,需要指定
Connection
值为Keep-Alive
。
-
2.3.2、请求首部字段
-
Accept
:声明能接受的数据格式(通配符*
)。 -
Host
:指定服务器域名。
2.3.3、响应首部字段
2.3.4、实体首部字段
-
Content-Encoding
:响应报文中 body 的编码格式(压缩方式)。 -
Content-Length
:响应报文中 body 的数据长度。-
TCP 粘包:HTTP 基于 TCP 通信,而 TCP 存在粘包问题。
-
HTTP 解决粘包:设置回车符、换行符作为 header 边界,通过
Content-Length
字段作为 body 边界。
-
-
Content-Type
:响应报文中 body 的数据格式。
RFC-2616 定义了 HTTP 的 47 种首部字段。
在实际通信中,还有 Cookie、Set-Cookie、Content-Disposition 等非正式的首部字段。
3、报文主体
HTTP 的报文主体,用于传输实体主体。
通常情况下,二者相同。
3.1、编码
如果在传输中对实体主体进行编码操作时,二者就不同。
- 内容编码:用于压缩传输
- 指明应用在实体内容上的编码格式,保持实体信息原样发送。
- 客户端接收并负责解码。
- 分块传输编码:用于分割发送
- 将实体主体分成多个块。
- 客户端接收并负责解码。
3.2、多部份集合对象
类似邮件的 MIME 机制,HTTP 也采纳了多部份集合对象。
通常在图片或文本文件上传时使用。
使用:Content-type 首部字段 + boundary
-
multipart/form-data:Web 表单文件上传
-
multipart/byteranges:多范围内容