07 HTTP报文

Posted by CodingWithAlice on April 21, 2021

07 HTTP报文

  • 总结

    1、HTTP 报文结构由 起始行 + 头部 + 空行 + 实体 组成,简单地说就是 header + body

    2、HTTP 报文可以没有 body,但必须要有 header,而且 header 后也必须要有空行

    3、请求头请求行 + 头部字段 构成,响应头状态行 + 头部字段 构成;

    4、请求行有三部分:请求方法、请求目标、版本号,如 GET /index HTTP/1.1

    5、状态行也有三部分:版本号、状态码、原因字符串,如 HTTP/1.1 200 OK

    6、头部字段是 key-value 的形式,用 : 分隔,不区分大小写,顺序任意,除了规定的标准头,也可以任意添加自定义字段,实现功能扩展

    7、HTTP/1.1唯一要求,请求头必须提供的头字段是 Host,标记虚拟主机名

TCP 报文结构

TCP 在实际要传输的数据之前 附加了一个 20 字节的头部数据,存储 TCP 协议必须的额外信息(例如 发送方的端口号、接收方的端口号、包序号、标志位 等等),这样数据包才能够正确传输,到了目的地后把头部去掉,就可以拿到真正的数据。

image-20210421150007032

HTTP 报文结构

由三部分组成:

  • 1、起始行(start line):描述请求或响应的基本信息
  • 2、头部字段集合(header):使用 key-value 形式更详细地说明报文
  • 3、消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据

其中1、2合称 请求头/响应头,3对应称为 body - 实体,形象化如下图:

image-20210421150042364

注意:

  • 1、HTTP 协议规定报文 必须有 header,但可以没有 body
  • 2、在 header 之后 必须要有一个“空行”,也就是 CRLF

可以看如下示例

image-20210421150113952

起始行:请求行 - 请求

请求行 - 简要地描述了客户端想要如何操作服务器端的资源。

  • 请求行由三部分构成:

    1、请求方法:是一个动词,如 GET/POST,表示对资源的操作

    2、请求目标:通常是一个 URI,标记了请求方法要操作的资源

    3、版本号:表示报文使用的 HTTP 协议版本

    可以参考如下示例:

    image-20210421150150873

起始行:状态行 - 响应

响应报文的起始行 -> 状态行 - 代表服务器响应的状态

  • 状态行由三部分构成:

    1、版本号:表示报文使用的 HTTP 协议版本

    2、状态码:一个三位数,用代码的形式表示处理的结果

    3、原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因

    可以参考如下示例:

    image-20210421150228721

头部字段

请求行或状态行 再加上 头部字段集合 就构成了 HTTP 报文里完整的 请求头或响应头,如下图:

image-20210421150307148

头部字段是 key-value 的形式,keyvalue 之间用 : 分隔,最后用 CRLF 换行表示字段结束。

需要注意下面几点:

1、字段名 不区分大小写,但首字母大写的可读性更好

2、字段名 不允许出现空格,可以使用连字符 -,但 不能使用下划线“_”

3、字段名 后面 必须紧接着 :不能有空格,而: 后的 字段值前可以有多个空格

4、字段的 顺序是没有意义的,可以任意排列不影响语义

5、字段 原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie

400 Bad Request - 请求报文格式有误

常用头字段

头部字段可以自定义,但主要也是为了实现各种功能,基本上可以分为四大类:

1、通用字段:在请求头和响应头里都可以出现;

2、请求字段:仅能出现在请求头里,进一步说明请求信息或者额外的附加条件;

3、响应字段:仅能出现在响应头里,补充说明响应报文的信息;

4、实体字段:它实际上属于通用字段,但专门描述 body 的额外信息

  • Host 字段

    属于请求字段,只能出现在 请求头,它同时也是唯一一个 HTTP/1.1 规范里要求 必须出现 的字段Host 字段告诉服务器这个请求应该由哪个主机来处理

  • User-Agent

    是请求字段,只出现在 请求头,它使用一个字符串来描述发起 HTTP 请求的客户端(可以传假的,不作数;有些爬虫会声明自己是 spider,可以反爬虫),服务器可以依据它来返回最合适此浏览器显示的页面

  • Date

    通用字段,但通常出现在 响应头 里,表示 HTTP 报文创建的时间,客户端可以使用这个时间再搭配其他字段决定缓存策略。

  • Server

    响应字段,**只能出现在 响应头 **里。它告诉客户端当前正在提供 Web 服务的软件名称和版本号,非必须

  • Content-Length

    表示报文里 body 的长度,也就是请求头或响应头 空行后面数据的长度

    如果没有这个字段,那么 body 就是不定长的,需要使用 chunked 方式 分段传输