lxfriday / give-me-job

To be a 30k code farmer
GNU General Public License v3.0
5 stars 1 forks source link

HTTP 报文格式 #97

Closed lxfriday closed 4 years ago

lxfriday commented 4 years ago

文章地址

lxfriday commented 4 years ago

HTTP 消息

图片来自 unsplash

年后第一篇,在家待着效率实在不高。最近在忙着总结前端面试相关的技术文档,等完善度达到70%或者更高的时候我将会开放出来!!!

HTTP 对前端有多重要这不用多说,这篇文章只介绍了 HTTP 消息的内容组成,如果下面的内容你还不熟悉,这说明你需要加把劲了!!

HTTP 消息由采用 ASCII 编码 的多行文本构成。在 HTTP/1.1 及早期版本中,这些消息通过连接公开地发送。在 HTTP/2 中,为了优化和性能方面的改进,曾经可人工阅读的消息被分到多个 HTTP 帧中。

来看看请求和响应实际是什么样的:

HTTP 请求

HTTP 响应

HTTP 消息组成

HTTP 请求和响应具有相似的结构,由以下部分组成︰

  1. 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败。这个起始行总是单行的;
  2. 一个可选的HTTP 头集合指明请求或描述消息正文;
  3. 一个空行指示所有关于请求的元数据已经发送完毕;
  4. 一个可选的包含请求相关数据的正文 (比如 HTML 表单内容), 或者响应相关的文档。正文的大小由起始行的 HTTP 头来指定;

起始行和 HTTP 消息中的 HTTP 头统称为请求头,而其有效负载被称为消息正文。

HTTP 消息

HTTP 请求

起始行

HTTP 请求是由客户端发出的消息,用来使服务器执行动作。起始行 (start-line) 包含三个元素:

  1. HTTP 方法;
  2. 请求目标 (request target),通常是一个 URL,或者是协议、端口和域名的绝对路径;
  3. HTTP 版本,定义了剩余报文的结构,作为对期望的响应版本的指示符;

请求头

不区分大小写的字符串,紧跟着冒号 (:) 和一个结构取决于 header 的值。 整个 header(包括值)由一行组成,这一行可以相当长。

请求头分为几组:

  1. 通用头(General headers),例如 Via,适用于整个报文;
  2. 请求头(Request headers),例如 User-AgentAccept-Type,通过进一步的定义(例如 Accept-Language),或者给定上下文(例如 Referer),或者进行有条件的限制 (例如 If-None) 来修改请求;
  3. 实体头(Entity headers),例如 Content-Length,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件。

HTTP header

请求体

请求的最后一部分是它的请求体(body)。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含 HTML 表单数据)。

HTTP 响应

起始行

HTTP 响应的起始行被称作状态行(status line),包含以下信息:

  1. 协议版本,通常为 HTTP/1.1
  2. 状态码 (status code);
  3. 状态文本 (status text);

一个典型的状态行是这样的:

HTTP/1.1 404 Not Found

响应头

不区分大小写的字符串,紧跟着的冒号 (:) 和一个结构取决于 header 类型的值。 整个 header(包括其值)表现为单行形式。

这些响应头可以分为几组:

  1. 通用头(General headers),例如 Via,适用于整个报文;
  2. 返回头(Response headers),例如 VaryAccept-Ranges,提供其它不符合状态行的关于服务器的信息
  3. 实体头(Entity headers),例如 Content-Length,适用于请求的 body。显然,如果请求中没有任何 body,则不会发送这样的头文件;

HTTP 响应

响应体

响应的最后一部分是响应体(body)。不是所有的响应都有 body:具有状态码 (如 201 或 204) 的响应,通常不会有 body。

Body 大致可分为三类:

  1. Single-resource bodies,由已知长度的单个文件组成。该类型 body 由两个 header 定义:Content-TypeContent-Length
  2. Single-resource bodies,由未知长度的单个文件组成,通过将 Transfer-Encoding 设置为 chunked 来使用 chunks 编码。
  3. Multiple-resource bodies,由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的;

总结

HTTP 请求体格式

POST /query HTTP/1.1
Host: web-api.juejin.im
Connection: keep-alive
Content-Length: 132
Origin: https://juejin.im
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: https://juejin.im/timeline
Accept-Encoding: gzip
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7

{"variables":{"type":"ARTICLE","since":"2019-12-17T02:22:52.801Z"},"extensions":{"query":{"id":"0d2f86267cfa529141a196314c2038e2"}}}

HTTP 响应体格式

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Tue, 18 Feb 2020 04:28:54 GMT
Content-Type: application/json
Content-Length: 56
Connection: close
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type,X-Agent,X-Token,X-Legacy-Token,X-Legacy-Uid,X-Legacy-Device-Id,X-Legacy-New-Token,X-Request-Id
Access-Control-Max-Age: 86400

{"data":{"followingActivityFeed":{"newItemCount":348}}}

补充

HTTP/1.x 报文有一些性能上的缺点:

  1. Header 不像 body,它不会被压缩;
  2. 两个报文之间的 header 通常非常相似,但它们仍然在连接中重复传输;
  3. 无法复用。当在同一个服务器打开几个连接时:TCP 热连接比冷连接更加有效;

HTTP2 的解决办法:

HTTP/2 引入了一个额外的步骤:它将 HTTP/1.x 消息分成帧并嵌入到流 (stream) 中数据帧和报头帧分离,这将允许报头压缩。将多个流组合,这是一个被称为多路复用 (multiplexing) 的过程,它允许更有效的底层 TCP 连接。

HTTP 帧现在对 Web 开发人员是透明的。在 HTTP/2 中,这是一个在 HTTP/1.1 和底层传输协议之间附加的步骤。Web 开发人员不需要在其使用的 API 中做任何更改来利用 HTTP 帧;当浏览器和服务器都可用时,HTTP/2 将被打开并使用。


关注公众号,回复 加群 ,添加号主微信,将会拉你进交流群,有任何问题都会回复,欢迎加入。

感谢阅读,欢迎关注我的公众号 云影 sky,带你解读前端技术,掌握最本质的技能。

公众号