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
协议必须的额外信息(例如 发送方的端口号、接收方的端口号、包序号、标志位 等等),这样数据包才能够正确传输,到了目的地后把头部去掉,就可以拿到真正的数据。
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
方式 分段传输。