Skip to main content

08 HTTP报文

报文结构

TCP 报文

HTTP 协议是一个纯文本的协议,头数据是 ASCII 码的文本。

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

1 和 2 经常被合称为**请求头或响应头,3 消息正文又称为实体或 body。**

HTTP 协议规定报文必须有 header,可以没有 body,在 header 之后必须要有一个空行,即 CRLF,十六进制的 0D0A。

请求行

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

  1. 请求方法:是一个动词,如 GET/POST,表示对资源的操作;
  2. 请求目标:通常是一个 URI,标记了请求方法要操作的资源;
  3. 版本号:表示报文使用的 HTTP 协议版本。

三个部分通常使用空格(space)来分隔,最后要用 CRLF 换行表示结束。

状态行

状态行(status line),服务器响应的状态。

  1. 版本号:报文使用的 HTTP 协议版本;
  2. 状态码:一个三位数,用代码的形式表示处理的结果(200:成功,500:服务器错误);
  3. 原因:数字状态码的补充,更详细的解释文字,帮助人理解原因。

头部字段

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

HTTP 头字段可以使用标准里的 Host、Connection 等已有头,也可以任意添加自定义头。

  1. 字段名不区分大小写;
  2. 字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线“_”;
  3. 字段名后面必须紧接着“:”,不能有空格,而“:”后的字段值前可以有多个空格;
  4. 字段的顺序是没有意义的,可以任意排列不影响语义;
  5. 字段原则上不能重复,除非该字段本身的语义允许(Set-Cookie)。

常用头字段

  1. 通用字段:在请求头和响应头里都可以出现;
  2. 请求字段:仅能出现在请求头里,进一步说明请求信息或者额外的附加条件;
  3. 响应字段:仅能出现在响应头里,补充说明响应报文的信息;
  4. 实体字段:属于通用字段,但专门描述 body 的额外信息。

Host

属于请求字段,只能出现在请求头里,是唯一一个 HTTP/1.1 规范里要求必须出现的字段,如果请求头里没有 Host,就是一个错误的报文。Host 字段告诉服务器这个请求应该由哪个主机来处理,当一台计算机上托管了多个虚拟主机,服务器端就需要用 Host 字段来选择。

User-Agent

请求字段,只出现在请求头里。使用一个字符串描述发起 HTTP 请求的客户端,服务器可以依据它来返回最合适此浏览器显示的页面。

Date

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

Server

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

Content-Length

实体字段,表示报文里 body 的长度,即请求头或响应头空行后面数据的长度。服务器根据这个字段知道后续有多少数据,可以直接接收。如果没有这个字段,body 就是不定长的,需要使用 chunked 方式分段传输。