07 HTTP报文
-
总结
1、
HTTP报文结构由 起始行 + 头部 + 空行 + 实体 组成,简单地说就是header+body2、
HTTP报文可以没有body,但必须要有header,而且header后也必须要有空行3、请求头由 请求行 + 头部字段 构成,响应头 由 状态行 + 头部字段 构成;
4、请求行有三部分:请求方法、请求目标、版本号,如
GET /index HTTP/1.15、状态行也有三部分:版本号、状态码、原因字符串,如
HTTP/1.1 200 OK6、头部字段是
key-value的形式,用:分隔,不区分大小写,顺序任意,除了规定的标准头,也可以任意添加自定义字段,实现功能扩展7、
HTTP/1.1里唯一要求,请求头必须提供的头字段是 Host,标记虚拟主机名
TCP 报文结构
TCP 在实际要传输的数据之前 附加了一个 20 字节的头部数据,存储 TCP 协议必须的额外信息(例如 发送方的端口号、接收方的端口号、包序号、标志位 等等),这样数据包才能够正确传输,到了目的地后把头部去掉,就可以拿到真正的数据。

HTTP 报文结构
由三部分组成:
- 1、起始行(start line):描述请求或响应的基本信息
- 2、头部字段集合(header):使用
key-value形式更详细地说明报文 - 3、消息正文(entity):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据
其中1、2合称 请求头/响应头,3对应称为 body - 实体,形象化如下图:

注意:
- 1、HTTP 协议规定报文 必须有 header,但可以没有 body
- 2、在 header 之后 必须要有一个“空行”,也就是
CRLF
可以看如下示例

起始行:请求行 - 请求
请求行 - 简要地描述了客户端想要如何操作服务器端的资源。
-
请求行由三部分构成:
1、请求方法:是一个动词,如
GET/POST,表示对资源的操作2、请求目标:通常是一个
URI,标记了请求方法要操作的资源3、版本号:表示报文使用的
HTTP协议版本可以参考如下示例:

起始行:状态行 - 响应
响应报文的起始行 -> 状态行 - 代表服务器响应的状态
-
状态行由三部分构成:
1、版本号:表示报文使用的
HTTP协议版本2、状态码:一个三位数,用代码的形式表示处理的结果
3、原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因
可以参考如下示例:

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

头部字段是 key-value 的形式,key 和 value 之间用 : 分隔,最后用 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方式 分段传输。