三、《图解HTTP》- 报文内的 HTTP信息

#tjhttp 三、《图解HTTP》- 报文内的 HTTP信息

知识点

  1. HTTP 请求报文结构。
  2. 请求报文和主体差异,介绍有关报文和主体相关的一些概念信息。
  3. 内容协商:什么是内容协商?关于内容协商的几种方式。

3.1 HTTP请求报文结构

请求和响应报文的结构如下:

HTTP请求报文结构

下面是有关请求报文请求和响应的案例。

请求报文请求和响应的案例

3.2 报文和主体差异

为了提高HTTP传输效率,在请求中可以通过HTTP请求报文和实体加工的方式对于报文原文进行“编码”,这里的编码并不是单指文本字符串,而是更抽象意义上的编码。

介绍具体的内容之前我们需要先分清楚两个术语:报文实体

报文:是HTTP通信中的基本单位,由8位组 字节流(octet sequence,其中octet为8个比特)组成,通过HTTP通信传输。

实体(entity):作为请求或响应的 有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。

为了理解实体的概念,需要了解有效载荷是怎么一回事:

负载)(英语:Payload):负载指的是需要传输的实体数据信息,这也是为什么叫数据实体的原因。当然也可以叫做信头与元数据,或称为开销数据,仅用于辅助数据传输。

**头(header):指的是在一块数据存储或传输之际在头追加的数据,这些信息是对数据区的描述。

元数据(英语:metadata):……为描述其他数据信息的数据。

划掉实体是因为术语实体(entity)被有效载荷(payload)代替,书中所提到2616版本很多解释已经被废弃了,现在RFC 2616 已经被 RFC 7230 、 7235 取

代了。

下面这篇文章中讨论了实体和载荷的区别,以及为什么要取代载荷

#109 (Clarify entity / representation / variant terminology) – Hypertext Transfer Protocol Wiki (ietf.org)

有关负载的解释

原文:

Replaced entity with payload and variant with representation. Cleaned up description of 204 status code (related to ticket #22) Rewrote section on Content-Location and refer to def in RFC2557.

另外维基上有一个关于生活当中“有效载荷”的术语解释,通过描述可以从侧面理解官方为什么突然要把实体的概念重新解释。

摘自维基百科“有效载荷”: 有效载荷是飞机运载火箭携带的物体。有时,有效载荷也指飞机或运载火箭能够承载的重量。根据任务的性质,载具的有效载荷可能是货物乘客机组人员弹药、科学仪器或实验或其他设备。如果可以选择性携带,那额外的燃料也会被视为有效载荷的一部分,如空中加油任务。

个人认为负载(叫负荷也可以)这个解释要比实体这个解释好理解一些(实体稍显抽象),并且不会丢失实体本身的含义。

接着我们通过对比Chrome和Edge浏览器,发现在目前的版本中均存在负载的概念,过去的版本中实际上这部分内容被放到报文的请求实体 中,很显然这是不严谨的,在那个时候被称作实体

当然这两年这部分悄悄做了调整,显然在后续RFC修订协议过程中这些浏览器也对于这些概念进行跟进,不知道有多少人关注过,嗯,又是一个小细节。

Edge的“负载”

Chrome的Payload

所以负载概念取代实体概念目的是防止混淆(因为确实很容易搞混),实际上实体也分为首部和其他信息,实体首部是对该负载的描述,而负载和其它一些信息(请求行/状态行、各种首部字段等等)组织成报文进行传输。

书中有这样的图帮助我们了解实体和报文的差别,这张图也能说明为什么很多解释会把报文和实体(有效负载)看做是订单和货物的关系。

请求和响应报文结构

更头疼的概念

实际上还用更容易混淆的概念,message bodypayload body

根据 RFC 7230

HTTP 报文的报文主体(message body)(如果存在的话)是用来运载请求或响应的有效载荷主体(payload body)的。除非应用了传输编码,报文主体等价于有效载荷主体

换句话说只有在应用了传输编码的时候,负载=实体首部+实体主体,目前主要应用的传输编码是Transfer-Encoding: chunked,也就是分块传输的去看下负载的概念会出现转变,否则可以简单看做是报文的请求Body。

HTTP报文的主体用于传输请求或响应的实体主体,对于主体的处理优化HTTP在后续的版本中实现了下面这些特性:

  1. 压缩传输
  2. 分块传输编码
  3. 多数据多对象集合

压缩传输

首先需要明确到的是压缩是在负载上面完成的,并且压缩需要保证信息不遗失的原样压缩,否则压缩不完整的数据会导致数据发生错误。

常见的压缩方式是下面几种,其中gzip是图片经常使用的压缩方式:

  • `gzip(GNU zip)
  • compress(UNIX 系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

压缩传输是有代价的,因为这个操作需要计算机完成,所以会增加服务器的工作量,不过这一点开销完全可以接受。

分块传输编码

实体主体分块的功能称为分块传输编码(Chunked TransferCoding),分块传输指的是传输编码会将实体内容拆分为多个块(chunck),也就是前文提到的Transfer-Encoding: chunked

需要注意在负载主体的最后一块会使用“0(CR+LF)”来标记块的大小。

多数据多对象集合

多数据多对象集主要包含如下内容:

  • mulitpart/form-data:在 Web 表单文件上传时使用;
  • mulitpart/byteranges:状态码 206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用;

需要使用多数据多对象集合,需要在HTTP中指定Content-Type 首部字段。

enctype 属性

多数据多对象集合的一个代表属性,主要的作用是告知服务器自己将会传输什么类型的数据。

最常见的多部分对象集合的实际应用就是使用 HTML 表单发送文件。文件是二进制数据(或被视为二进制数据),而所有其他数据都是文本数据。由于 HTTP 是一种文本协议,因此对处理二进制数据有特殊要求。

3.3 内容协商

内容协商比较典型的案例是国际化,内容协商有点类似转译,服务器和客户端之间需要协商出一种最为合适的“中间”语言进行交流,然后按照字符集和编码格式进行交互。

基准和判断的基准是下面这几个首部字段的信息:

Accept
Accept-Charset
Accept-Encoding
Accept-Language
Content-Language

比如下面的维基在请求请求首部中就用到了这些信息。

content-encoding: gzip
content-language: zh
content-length: 17396
accept-ch: Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-Full-Version-List,Sec-CH-UA-Model,Sec-CH-UA-Platform-Version

3.3.1 内容协商方式

内容协商的基本准则如下:

  1. 依靠客户端设置HTTP首部(也叫服务驱动内容协商或者说主动协商),内容协商最为标准的方式。
  2. 服务器返回300或406,代理驱动方式或者响应协商机制。

服务器驱动协商(Server-driven Negotiation)

由服务器端进行内容协商。服务端协商中客户端请求随同URL会发送一份消息头表明自己的倾向性,服务器按照这个倾向性选择合适的资源返回。

服务器驱动的优点是充分利用HTTP协议规范减少额外的行为,因为是内容协商而不是格式协商,决定权实际上还是在服务端这一边。

当然这样的优点导致的代价是服务端的复杂性增加,因为需要“猜测”客户端的信息,同时可能会导致客户端发送报文越来越复杂。

客户端驱动协商(Agent-driven Negotiation)

由客户端进行内容协商的方式,用户协商类似用户选择浏览器的类型自动进行切换。

注意客户端驱动如果服务端不能回应客户端的请求,会退化为 服务器驱动协商,客户端驱动为了获取自己想要的内容需要 第二次发送请求(第一次获取列表,第二次才是得到资源),可见客户端的驱动模式并不是一种常用的方式。

代理驱动型内容协商机制

针对透明代理的改良方案,代理驱动主要是解决服务端协商的比较显著的痛点:规模化问题。

所谓的规模化问题指的当服务端请求出现大量资源并且需要添加首部情况下,会出现请求体积膨胀并且精确信息的发送也带来信息泄露问题。

注意代理驱动和透明代理存在一定区别,它使用了HTTP协议自创建依赖就支持又称为响应代理机制的东西,这种机制也是和客户端驱动协商类似,返回资源列表给用户进行选择然后需要第二次请求获取需要的资源。而透明代理借用了 Vary首部完成协议兼容,有点类似“旁外招”。

所以代理驱动虽然减轻了服务端和客户端形成“中间商”参考的模式,但是也避免不了第二次请求的问题。

透明协商(Transparent Negotiation)

透明代理被代理驱动型内容协商机制取代。

透明协商机制试图从服务器上去除服务器驱动协商所需的负载,并用中间代理来代表客户端以使与客户端的报文交换最小化。

这是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。但是因为后续历史没被认可所以被遗弃。

透明协商在HTTP并没有提供相应的规范,所以HTTP/1.1规范中没有定义任何透明协商机制,但定义了Vary首部,所以透明代理主要使用了Vary这个额外的字段完成协议兼容。

Vary 响应首部是什么? 在HTTP1.1协议中被添加,是通过服务器响应给客户端协商内容的时候一并返回的,服务端最终使用了那个首部清单。 最大的受益者不是客户端反倒是缓存服务器,缓存服务器检查发现Vary字段之后启用透明协商机制委托传输。缓存服务器是啥?请看这篇文章[《网络是怎么样连接的》读书笔记 - 汇总篇]中关于负载均衡概念的介绍。

Alternates 首部

同样没受到认可被遗弃。网上都搜不到啥资料,忽略即可。

3.4 小结

上面介绍了众多的 内容协商方式,实际上仔细观察现在的网站会发现服务器驱动协商代理驱动型内容协商机制为主。

前者是WEB服务提供商可以根据用户的请求推送喜欢的内容,并且不需要二次发送请求节省带宽,适合绝大多数WEB用户,当然用户体验取决于服务端应用程序开发者的水平。

代理驱动型内容协商机制则多用于支持国际化的网站,比如一些大商城或者百科等,比较典型的比如Apple和维基百科等这些网站,提供了“建议”选项询问用户选择哪种语言进行浏览。

而客户端代理主动权掌握在用户手上,服务端无法把控的同时不利于商业推广,所以大部分WEB网站会“屏蔽”这种方式,另一方面代理驱动能减轻服务器压力同时兼容了客户端驱动的特点,所以被代理驱动取代也十分正常。

最后是透明代理,透明代理使用的“旁门左路”的自定义的协议不怎么通用的,所以被淘汰以及被代理驱动取代也很正常。

原文地址:https://cloud.tencent.com/developer/article/2071373

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340