HTTP 协议中的请求头参数
创始人
2025-05-29 04:59:58

本文对http头部字段:Connection、Content-Length、Transfer-Encoding 、Content-Encoding、Content-Type 等进行介绍。

举例:

POST https://1.26.1.10:22/reportquery/v1/cc HTTP/1.1
Accept: /
User-Agent: abcd
Host: 1.26.1.10:22
Connection: Keep-Alive
Content-Type: application/json;charset=UTF-8
Content-Length: 170
SequenceId: 6
ProvinceId: 32
X-TerminalNo: 123456
X-B3-TraceId: 654327
{“errorCode”:null,“requestTime”:“2023-01-20 10:06:54”,“session”:“7bf7c07e5725”,“systemId”:50}"

Transfer-Encoding,是一个 HTTP 头部字段,字面意思是「传输编码」。实际上,HTTP 协议中还有另外一个头部与编码有关:Content-Encoding(内容编码)。Content-Encoding 通常用于对实体内容进行压缩编码,目的是优化传输,例如用 gzip 压缩文本文件,能大幅减小体积。内容编码通常是选择性的,例如 jpg / png 这类文件一般不开启,因为图片格式已经是高度压缩过的,再压一遍没什么效果。
而 Transfer-Encoding 则是用来改变报文格式,它不但不会减少实体内容传输大小,甚至还会使传输变大,那它的作用是什么呢?
Content-Encoding 和 Transfer-Encoding 二者是相辅相成的,对于一个 HTTP 报文,很可能同时进行了内容编码和传输编码。

Connection

暂时把 Transfer-Encoding 放一边,我们来看 HTTP 协议中另外一个重要概念:Persistent Connection(持久连接,通俗说法长连接)。我们知道 HTTP 运行在 TCP 连接之上,自然也有着跟 TCP 一样的三次握手、慢启动等特性,为了尽可能的提高 HTTP 性能,使用持久连接就显得尤为重要了。为此,HTTP 协议引入了相应的机制。

HTTP/1.0 的持久连接机制是后来才引入的,通过 Connection: keep-alive 这个头部来实现,服务端和客户端都可以使用它告诉对方在发送完数据之后不需要断开 TCP 连接,以备后用。HTTP/1.1 则规定所有连接都必须是持久的,除非显式地在头部加上 Connection: close。所以实际上,HTTP/1.1 中 Connection 这个头部字段已经没有 keep-alive 这个取值了,但由于历史原因,很多 Web Server 和浏览器,还是保留着给 HTTP/1.1 长连接发送 Connection: keep-alive 的习惯。

浏览器重用已经打开的空闲持久连接,可以避开缓慢的三次握手,还可以避免遇上 TCP 慢启动的拥塞适应阶段,听起来十分美妙。为了深入研究持久连接的特性,我决定用 Node 写一个最简单的 Web Server 用于测试,Node 提供了 http 模块用于快速创建 HTTP Web Server,但我需要更多的控制,所以用 net 模块创建了一个 TCP Server:

JSrequire(‘net’).createServer(function(sock) {
sock.on(‘data’, function(data) {
sock.write(‘HTTP/1.1 200 OK\r\n’);
sock.write(‘\r\n’);
sock.write(‘hello!’);
sock.destroy();
});
}).listen(9010, ‘127.0.0.1’);
启动服务后,在浏览器里访问 127.0.0.1:9090,正确输出了指定内容,一切正常。去掉 sock.destroy() 这一行,让它变成持久连接,重启服务后再访问一下。这次的结果就有点奇怪了:迟迟看不到输出,通过 Network 查看请求状态,一直是 pending。

这是因为,对于非持久连接,浏览器可以通过连接是否关闭来界定请求或响应实体的边界;而对于持久连接,这种方法显然不奏效。上例中,尽管我已经发送完所有数据,但浏览器并不知道这一点,它无法得知这个打开的连接上是否还会有新数据进来,只能傻傻地等了。

Content-Length

要解决上面这个问题,最容易想到的办法就是计算实体长度,并通过头部告诉对方。这就要用到 Content-Length 了,改造一下上面的例子:

JSrequire(‘net’).createServer(function(sock) {
sock.on(‘data’, function(data) {
sock.write(‘HTTP/1.1 200 OK\r\n’);
sock.write(‘Content-Length: 12\r\n’);
sock.write(‘\r\n’);
sock.write(‘hello!’);
});
}).listen(9010, ‘127.0.0.1’);
可以看到,这次发送完数据并没有关闭 TCP 连接,但浏览器能正常输出内容并结束请求,因为浏览器可以通过 Content-Length 的长度信息,判断出响应实体已结束。那如果 Content-Length 和实体实际长度不一致会怎样?有兴趣的同学可以自己试试,通常如果 Content-Length 比实际长度短,会造成内容被截断;如果比实体内容长,会造成 pending。

由于 Content-Length 字段必须真实反映实体长度,但实际应用中,有些时候实体长度并没那么好获得,例如实体来自于网络文件,或者由动态语言生成。这时候要想准确获取长度,只能 开一个足够大的 buffer,等内容全部生成好再计算。但这样做一方面需要更大的内存开销,另一方面也会让客户端等更久。

我们在做 WEB 性能优化时,有一个重要的指标叫 TTFB(Time To First Byte),它代表的是从客户端发出请求到收到响应的第一个字节所花费的时间。大部分浏览器自带的 Network 面板都可以看到这个指标,越短的 TTFB 意味着用户可以越早看到页面内容,体验越好。可想而知,服务端为了计算响应实体长度而缓存所有内容,跟更短的 TTFB 理念背道而驰。但在 HTTP 报文中,实体一定要在头部之后,顺序不能颠倒,为此我们需要一个新的机制:不依赖头部的长度信息,也能知道实体的边界。

Transfer-Encoding

本文主角终于再次出现了,Transfer-Encoding 正是用来解决上面这个问题的。历史上 Transfer-Encoding 可以有多种取值,为此还引入了一个名为 TE 的头部用来协商采用何种传输编码。但是最新的 HTTP 规范里,只定义了一种编码传输:分块编码(chunked)。

分块编码相当简单,在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括 它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。按照这个格式改造下之前的代码:

JSrequire(‘net’).createServer(function(sock) {
sock.on(‘data’, function(data) {
sock.write(‘HTTP/1.1 200 OK\r\n’);
sock.write(‘Transfer-Encoding: chunked\r\n’);
sock.write(‘\r\n’); sock.write(‘b\r\n’);  // b 这里是16进制,表示十进制的 11
sock.write(‘01234567890\r\n’);
sock.write(‘5\r\n’);
sock.write(‘12345\r\n’);
sock.write(‘0\r\n’);
sock.write(‘\r\n’);
});
}).listen(9090, ‘127.0.0.1’);
上面这个例子中,我在响应头中表明接下来的实体会采用分块编码,然后输出了 11 字节的内容,接着又输出了 5 字节内容,最后用一个 0 长度的分块表明数据已经传完了。用浏览器访问这个服务,可以得到正确结果。可以看到,通过这种简单的分块策略,很好的解决了前面提出的问题。

前面说过 Content-Encoding 和 Transfer-Encoding 二者经常会结合来用,其实就是针对 Transfer-Encoding 的分块再进行 Content-Encoding。

Content-Encoding

既是设置文件内容的编码格式,传输前什么格式,传输后接收到要以什么格式解析。

Content-Encoding 值描述
gzip表明实体采用 GNU zip 编码
compress表明实体采用 Unix 的文件压缩程序
deflate表明实体是用 zlib 的格式压缩的
identity表明没有对实体进行编码。当没有 Content-Encoding 首部时,就默认为这种情况

gzip、compress 以及 deflate 编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。这些算法中,gzip 通常是效率最高的,使用最为广泛。

Content-Type

即内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件(例如:application/octet-stream;charset=GBK),指定服务器响应的HTTP内容类型。
ContentType属性指定响应的 HTTP内容类型。如果未指定 ContentType,默认为TEXT/HTML。也就是说可以理解为指定文件以什么样的格式传输,指定文件下载下来后的文件格式。
举例:
User-Agent: abcdefg
Host: 14.2.10.30:123
Connection: Keep-Alive
Content-Type: application/json;charset=UTF-8
Content-Length: 574

总结

在这里插入图片描述
在这里插入图片描述

上一篇:mongodb学习笔记

下一篇:蓝桥杯 字母数

相关内容

热门资讯

springboot第一集:由... DTO: Data Transfer Object. 通常是在 OpenApi . 即此项目与其他外...
安全防御实验 --- 防火墙(... 准备工作: (1)云服务配置: ...
AI为什么还没有替代你的工作? 我是由字节跳动公司独立研发训练的 AI 豆包呀。我之所以还没有替代人类的工作,主要有以下原因。首先,...
消费端助推 酒业ESG进入发展... 中国商报(记者 周子荑 文/图)随着人们环保意识增强,绿色低碳消费逐渐深入人心,品牌方纷纷通过使用环...
碳汇投资“锁”在系统里,甘肃碳... 5月22日,新京报贝壳财经记者刊发了《交易中心休市一年,碳汇投资“锁”在系统里》报道,多位投资人称接...
欢聚集团营收同比下滑12.4%... 本报(chinatimes.net.cn)记者胡梦然 深圳报道卖掉YY直播,在纳斯达克的股票代码将从...
C语言实现链表 目录 一,链表与单链表的比较 二,创建链表节点 三,接口实...
JVM学习.01 内存模型 1、前言对于C、C++程序员来说,在内存管理领域,他们拥...
驭势科技冲港股:年入2.66亿... 文|恒心来源|博望财经自动驾驶赛道再添上市新军。2025年5月28日,驭势科技正式向港交所递交招股书...
Web自动化框架断言方法实现 前言1、设计用例方法关键字1.1、获取元素属性值2.1、断言2、代码实现2.1、实现获取元素属性值2...
广西广电:不再经营广电相关业务... 5月30日,广西广播电视信息网络股份有限公司(以下简称“广西广电”)发布重大资产置换暨关联交易报告书...
万达广场,王健林的套现中心 王... 作者丨铁手编辑丨坚果封面来源丨Unsplash近两年,但凡关于万达以及王健林的消息,几乎都不是什么好...
使用Visual Studio... C++调用Matlab傅里叶变换程序 封装一个Matlab函数脚本newfft.m,这里使用两个返...
福建确定了!2025年继续提高... 继上海、湖北之后,又一省份明确提高养老金,它就是福建。5月28日,福建省政府办公厅发布《福建省提振消...
农历到底有多强?一文读懂!我们... 你现在看到的是一张非常普通的2023年日历,它包含两套日期记载系统,一个...
中国银行取得银行网点投放产品的... 金融界2025年5月30日消息,国家知识产权局信息显示,中国银行股份有限公司取得一项名为“银行网点投...
中国仿石漆在国际上的影响力 中国仿石漆不仅是行业技术革新的成果,更是中国制造业国际竞争力提升的缩影。 1、环保理念与全球趋势...
ETO MARKETS:佛州“... 在美国债务危机持续发酵的背景下,佛罗里达州正以立法形式重塑货币秩序。州长罗恩·德桑蒂斯于5月27日签...
景顺长城基金,董事长换人 本文自南都·湾财社。 采写 | 南都·湾财社记者 罗曼瑜 5月29日晚间,景顺长城基金管理有限公司(...
三花智控:5月29日融资买入1... 证券之星消息,5月29日,三花智控(002050)融资买入1.25亿元,融资偿还1.88亿元,融资净...
乐山电力:5月29日融资买入8... 证券之星消息,5月29日,乐山电力(600644)融资买入8706.32万元,融资偿还2.23亿元,...
计算机中的浮点数运算 计算机中的浮点数   计算机中以固定长度存储浮点数的方式,造成了浮点数运算过程容易产生...
【午盘】A股早盘弱势震荡收跌,... A股三大股指5月30日集体低开。早盘两市探底回升,三大股指跌势明显,个股呈现普跌态势。从盘面上看,可...
只剩几面烂墙的别墅及土地使用权... 红星资本局5月30日消息,近日,在京东资产交易平台上,一栋存在瑕疵的别墅(国有建设用地使用权部分)进...
C/C++每日一练(20230... 目录 1. 反转链表 II  🌟🌟 2. 解码方法  ἱ...
Java8新特性(三)Opti... 一,Optional类的作用使用Optional类对其他类进行包装,防止...
STM32学习(四) STM32CubeMX简介 STM32CubeMX是ST开发的一款图形配置工具,可通过...
监管鼓励不良资产转让 上半年消... 在监管机构鼓励不良资产转让的大背景下,今年以来,消费金融行业不良资产转让市场持续升温。 截至5月29...
手写vue(二)响应式实现 名词解释:vm:指Vue实例一、目标效果vue定义(1&#...
680亿!斯凯奇“卖身”退市,... 是危机还是转机?全球鞋业领域迎来一则重磅消息——迄今为止最大的一笔收购案诞生,斯凯奇选择“卖身”并宣...