HTTP 是 Web浏览器与服务器进行任何数据交换的基础协议,是一种客户端—服务器(client-server)协议。它依赖于TCP协议进行通讯,同时有可能依赖于应用层DNS协议以及通常被认为是传输层的TLS协议。
作为一种网络协议,了解它的报文结构通常是最基础最重要的,本文将简述HTTP报文结构。
需要额外说明的是,HTTP1.1以及更早的HTTP协议报文都是语义可读的。在HTTP2中,这些报文被嵌入到了一个新的二进制Frame中。HTTP2的帧允许实现很多优化,比如报文标头的压缩以及多路复用。即使使用HTTP2协议,客户端仍然会在收到帧后重组原始的HTTP1.1请求。因此,用HTTP1.1格式来理解HTTP2报文仍旧有效。
有两种 HTTP 报文的类型,请求与响应。
请求报文
请求由以下元素组成:
- 一个 HTTP Request Method,通常是由一个动词,像 GET、POST 等,或者一个名词,像 OPTIONS、HEAD 等,来定义客户端执行的动作。典型场景有:客户端意图抓取某个资源(使用GET);发送 HTML 表单的参数值(使用POST);以及其他情况下需要的那些其他操作。
- 要获取的那个资源的路径——去除了当前上下文中显而易见的信息之后的 URL Path,比如说,它不包括协议(
http://
)、域名或是 TCP 的端口(这里的端口是 80)。例如,请求的目标主机除了会在更底层的TCP协议中被确定,还会在Headers中的Host字段中表明,所以目标主机的URL不会出现在Path字段中 - HTTP 协议版本号。
- 为服务端表达其他信息的可选请求标头 Headers。
- 请求体(Body),类似于响应中的请求体,一些像 POST 这样的方法,请求体内包含需要了发送的资源。
下面是一个HTTP请求报文的实际例子:
1 | GET /content.json?t=1578750478 |
Request Methods
HTTP 定义了一组请求方法,以表明要对给定资源执行的操作。表明针对给定的资源,客户端要执行的期望动作。
GET
方法请求一个指定资源的表示形式,使用 GET 的请求应该只被用于获取数据。HEAD
方法请求一个与 GET 请求的响应相同的响应,但没有响应体。POST
方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。PUT
方法用有效载荷请求替换目标资源的所有当前表示。DELETE
方法删除指定的资源。CONNECT
方法建立一个到由目标资源标识的服务器的隧道。OPTIONS
方法用于描述目标资源的通信选项。TRACE
方法沿着到目标资源的路径执行一个消息环回测试。PATCH
方法用于对资源应用部分修改。
响应报文
响应报文包含了下面的元素:
- HTTP 协议版本号。
- 一个状态码(status code),来指明对应请求已成功执行或是没有,以及相应的原因。
- 一个状态信息,这个信息是一个不权威、简短的状态码描述
- HTTP Headers - 标头,与请求标头类似。
- 可选项,一个包含了被获取资源的主体。
下面是一个HTTP响应报文的实际例子:
1 | 200 OK |
Response Status
HTTP 响应状态码用来表明特定 HTTP 请求是否成功完成。响应被归为以下五大类:
- 信息响应 (100–199)
- 成功响应 (200–299)
- 重定向消息 (300–399)
- 客户端错误响应 (400–499)
- 服务端错误响应 (500–599)
更详细的错误码可以查阅 MDN Web Docs - HTTP Status
HTTP Headers
HTTP 标头(header)允许客户端和服务器通过 HTTP 请求(request)或者响应(response)传递附加信息。一个 HTTP 标头由它的名称(不区分大小写)后跟随一个冒号(:),冒号后跟随它具体的值。该值之前的空格会被忽略。
自定义专用的标头之前可以与 X- 前缀一起使用,但是这种用法被 IETF 在 2012 年 6 月发布的 RFC 6648 明确弃用,原因是其会在非标准字段成为标准时造成不便。
根据不同的消息上下文,标头可以分为:
- Request header: 请求标头包含有关要获取的资源或客户端或请求资源的客户端的更多信息。
- Response header: 响应标头包含有关响应的额外信息,例如响应的位置或者提供响应的服务器。
- Representation header: 表示标头包含资源主体的信息,例如主体的 MIME 类型或者应用的编码/压缩方案。
- Payload header: 有效负荷标头包含有关有效载荷数据表示的单独信息,包括内容长度和用于传输的编码。
所以,有一部分Headers只会出现在请求报文中,有一部分只会出现在响应报文中,而还有一部分则即在请求报文中合法也在响应报文中合法。
更多的HTTP Headers可以在MDN Web Docs - HTTP 标头(header)中查询
常见Request Headers
- Host 请求的目标主机名和端口号
- Referer 指明了请求当前资源的原始资源的URL
- User-Agent 将创建请求的浏览器和用户代理名称等信息传达给服务器
例如:User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0)
一些Accept Headers用于告知服务器,客户端可以接受的数据类型或格式
- Accept 该字段可以通知服务器 客户端能够接收处理的媒体类型及优先级。
例如:Accept: text/html,application/xhtml+xml,application/xml;q=0.3
- Accept-Charset 通知服务器 客户端支持的字符集及字符集的相对优先顺序。
例如:Accept-Encoding: gzip, deflate
- Accept-Encoding 用来告知服务器,客户端支持的内容编码及内容编码的优先级顺序。
… …
常见Response Headers
- Server 服务器程序名称和版本
- Date 消息产生的时间
- Age 源服务器在多久前创建了响应 单位为秒。
还有一些指示响应Body元信息的Headers
- Content-Type
- Content-Encoding
- Content-Language
- Content-Length
- Content-Range
… …