学习笔记 图解HTTP 第六章:HTTP首部
HTTP报文首部HTTP协议的请求和响应报文中必定包含HTTP首部。其提供所需要的信息给客户端和服务器。HTTP请求报文下图为请求报文的构成:示例:GET /api/v1/zy?pageNo=1&pageSize=10 HTTP/1.1Host: 121.41.5.5Connection: keep-aliveAccept: application/json, text/plain, /A
HTTP报文首部

HTTP协议的请求和响应报文中必定包含HTTP首部。其提供所需要的信息给客户端和服务器。
HTTP请求报文
下图为请求报文的构成:
示例:
GET /api/v1/zy?pageNo=1&pageSize=10 HTTP/1.1
Host: 121.41.5.5
Connection: keep-alive
Accept: application/json, text/plain, /
Access-Token:xxxxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
HTTP响应报文

示例:
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Sat, 18 Jul 2020 12:21:59 GMT
Content-Type: application/json
Content-Length: 550
Connection: keep-alive
Content-Encoding: gzip
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
在报文众多的字段当中,HTTP首部字段包含的信息最为丰富,首部字段同时存在于请求和响应报文内,并涵盖HTTP报文相关的内容信息。
HTTP首部字段
HTTP首部字段传递重要信息
HTTP首部字段是构成HTTP报文的要素之一。使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
HTTP首部字段结构
HTTP首部字段是由首部字段名和字段值构成的,中间采用冒号:分隔。同时字段值可以由多个值构成。
例如:Keep-Alive: timeout=15, max=100
如果HTTO首部字段重复了会如何?
答:这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。
4种HTTP首部字段类型
HTTP首部字段根据实际用途被分为以下4种类型
- 通用首部字段(General Header Fields):请求报文和响应报文都会使用的首部。
- 请求首部字段(Request Header Fields):从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、相应内容相关优先级等信息。
- 响应首部字段(Response Header Fields):从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
HTTP/1.1 首部字段一览
HTTP/1.1规范了如下47种首部字段(RFC2616)。





非 HTTP/1.1 的首部字段
我们在HTTP协议通信交互种使用到的首部字段,不限于RFC2616中定义的那47种首部字段,还有Cookie,Set-Cookie和Content-Disposition等在其他RFC中定义的首部字段,使用频率也很高。
这些非正式的首部字段统一归纳在RFC4229 HTTP Header Field Registrations中。
End-to-end首部和Hop-by-hop首部
HTTP首部字段将定义成缓存代理和非缓存代理的行为,分成2种类型。
- 端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求/响应对应的最终接受目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。 - 逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后版本中,如果要使用hop-by-hop首部,需提供Connection首部字段。
下面列举了HTTP/1.1中的逐跳首部字段。除了这8个首部字段之外,其他所有字段都属于端到端首部。
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
HTTP/1.1通用首部字段
Cache-Control
通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
指令的参数是可选择的,通过逗号分隔。
例如:Cache-Control: private, max-age=0, no-cache
缓存请求响应

缓存响应指令
- public:可向任意方提供响应的缓存
- private:仅向特定用户返回响应
- no-cache:缓存前必须先确认其有效性
- no-store:不缓存请求或响应的任何内容
- no-transform:代理不可更改媒体类型
- must-revalidate:可缓存但必须再向源服务器进行确认
- proxy-revalidate:要求中间缓存服务器对缓存的响应有效性再进行确认
- max-age=[秒]:响应的最大Age值
- s-maxage=[秒]:公共缓存服务器响应的最大Age值
- cache-extension:新指令标记(token)
no-cache指令
public可以对任意用户进行缓存,private则只以特定的用户作为对象,与public相反。
no-cache:从客户端的角度来说:请发送新的源服务器的资源
从源服务器的角度来说:在每次使用缓存之前,先和源服务器确认其有效性
使用no-cache是为了防止从缓存中返回过期的资源。
只能在响应指令中指定该参数:Cache-Control:no-cache=Location
指定 某某 不能使用缓存:
由服务器返回的响应中,如果报文首部字段Cache-Control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存,换言之其他没有被指定到的首部字段可以使用缓存。
no-store指令
Cache-Control:no-store
使用该指令,表示不能进行缓存,no-cache是不缓存过期的资源,两者不同。
指定缓存期限:s-maxage 和 max-age指令
Cache-Control: s-maxage=600单位(秒)
这两个指令的功能差不多,s-maxage只能适用于供多个用户使用的公共缓存服务器,且当使用s-maxage后,直接忽略Expires首部字段和max-age指令。
must-revalidate 和 proxy-revalidate指令
这两个指令类似,会向源服务器验证即将返回的响应缓存 是否有效。
只不过前者是代理向源服务器验证,后者是所有的缓存服务器。
no-transform指令
规定了 无论是在请求还是响应,缓存都不能改变实体主体的媒体类型。
Connection
该首部字段有两个作用:
- 控制 哪些首部字段不转发给代理
- 管理持久连接


在HTTP/1.1之前的版本里,默认都是非持久连接,所以要指定Connection: keep-alive。
Date
首部字段Date用来表示创建该HTTP报文的时间,日期。
格式采用RFC1123中规定的格式:Date: Sun, 26 Jul 2020 08:23:52 GMT
这里的时间是世界时,要加八个小时才能换算成国内的北京时间。
Trailer
该字段会事先说明在报文主体之后,还有哪些首部字段,一般应用在分块传输编码时。

Transfer-Encoding
该字段规定了传输报文主体时采用的编码方式。(仅对分块传输编码有效)Transfer-Encoding: chunked
Via
VIa用于追踪请求和响应的传输路径。报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。
Warning
该首部通常会告知用户一些与缓存相关的警告。
HTTP/1.1中定义了7种警告:

请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
Accept
Accept: application/json, text/plain, */*
Accept首部字段可以通知服务器,用户代理能够处理的媒体类型及相对优先级。
使用q=来额外表示权重值:q的范围是0~1,1最大。不指定q值时,默认权重为q=1.0
Accept-Charset
用来通知服务器,用户代理支持的字符集及相对的优先顺序。与Accept类似,也有权重值q。
该首部字段应用于内容协商机制的服务器驱动协商。Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
Accept-Encoding
Accept-Encoding: gzip, deflate
用来告知服务器,用户代理支持的内容编码及优先级顺序。可一次指定多种内容编码
几个内容编码的格式:
- gzip
由文件压缩程序gzip(GNU zip)生成的编码格式,采用Lempel-Ziv算法及32位循环冗余校验(CRC) - compress
由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch算法(LZW) - deflate
组合使用zlib格式及由deflate压缩算法生成的编码格式 - identity
不执行压缩或不会变化的默认编码格式
可以使用 * 作为通配符,指定任意编码格式
Accept-Language
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
用来告知服务器,用户代理能够处理的自然语言集(中文、英文),以及相对优先级。
在上述例子种,如果服务器有中文资源,则客户端会要求返回中文对应的响应,如果没有,则会要求返回英文版响应。
Authorization
用于告诉服务器,用户代理的认证信息(证书值)。
客户端会在接收到服务器返回的401状态码后(要求认证),把首部字段Authorization加入请求中。
Expect
Expect: 100-continue
用Expect来告知服务器期望出现的某种特定行为。如果服务器无法理解期望Expect而发生错误时,会返回 417 Expectation Failed。
From
用于告知服务器,使用用户代理的用户的Email地址。也可能因为代理不同,而将Emain记录在User-Agent首部字段内。
Host
HTTP/1.1规范内唯一一个指定必须包含在请求内的首部字段:HostHost: 121.41.5.5
该字段明确指出了请求的主机名(和端口号)。
当请求被发送至服务器时,请求中的主机名(一般是域名)会用IP地址(DNS解析)直接替换解决。但如果此时,相同IP地址下部署运行着多个域名(被请求的服务器端),那么服务器就会无法理解究竟是哪个域名对应的请求。这时就需要Host字段来指明请求的主机名。
If-Match
形如If-xxx这种样式的请求首部字段,都被称为条件请求。服务器在接收到附带条件的请求后,只有判断 这个条件为True时,才会执行请求。
当If-Match值与ETag值匹配时,服务器才会接收请求
当If-Match值为星号*时,服务器就会忽略。
Proxy-Authorization
接收到代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。
这个字段与 Authorization首部字段相同,不同之处在于该字段的认证行为是在客户端与代理之间,而后着是在客户端和服务器之间的认证。
Range
Range: bytes=5001-10000
该字段可以只获取部分资源,告知服务器,所请求资源的指定范围。
服务器处理成功后会返回206 Partial Content响应,如果无法处理范围请求,则会返回200 OK和全部资源。
Referer
Referer: http://www.xxx.com/index.html
查看Referer就可以知道请求的URI是从哪个Web页面发起的。
User-Agent
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
该首部字段会将创建请求的浏览器和用户代理名称等信息传达给服务器。
如果请求经过代理,那么也很可能会被添加上代理服务器的名称。
响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
Accept-Ranges
该字段告诉客户端,服务器是否能处理范围请求,可以处理则值为bytes,不能处理为none。
Age
该字段告诉客户端,源服务器在多久前创建了响应。字段值的单位为秒。
ETag
告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的Etag值。
强ETage值和弱ETag值
强ETag值:无论实体资源发生多么细微的变化都会改变其值。etag: "FBC9EC8CC79FF1CC7C105E57AD798C96"
弱ETag值:只用于提示资源是否相同 ,只有资源发生了根本改变,产生差异时才会改变ETag值,这时回在字段值最开始处附加W/。etag: W/"FBC9EC8CC79FF1CC7C105E57AD798C96"
Location
该字段可以将响应接收方引导至某个与请求URI位置不同的资源上。
一般而言该字段会配合 3xx:Redirection的 响应,提供重定向的URI。几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源进行访问。
Proxy-Authenticate
该字段会把由代理服务器所要求的认证信息发送给客户端,
它和之前请求响应里的客户端与服务器之间的HTTP访问认证的行为相似,不同之处在于其认证行为是在客户端和代理之间进行的。客户端与服务器之间进行认证时,首部字段WWW-Authorization有着相同的作用。
Retry-After
Retry-After:120
该字段告知客户端应该在多久之后再次发送请求,主要配合状态码503 Service Unavailable响应,或3xx Redirect响应一起使用。
字段值可以指定为具体的日期(GMT格式等),也可以是创建响应后的秒数。
Server
Server: nginx/1.10.3 (Ubuntu)
该字段告知客户端,当前服务器上安装的HTTP服务器应用程序的信息,包括软件名称、版本号等。
Vary

Vary:Accept-Language
Vary可对缓存进行控制,源服务器会向代理服务器传达关于本地缓存使用方法的命令。
从代理服务器接收到的源服务器返回包含Vary指定项的响应后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存,如果Vary指定的首部字段不相同,则要从源服务器重新获取资源。
WWW-Authenticate
WWW-Authenticate:Basic realm="Usagidesign Auth"
该字段用于HTTP访问认证,它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic或Digest)和带参数提示的质询(challenge)。状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate。
实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
Allow
Allow:GET,HEAD
用于通知客户端,服务器能够支持Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回。
Content-Encoding
Content-Encoding:gzip
会告知客户端,服务器对实体主体部分选用的内容编码方式(内容编码方式是指在不丢失实体信息的前提下所进行的压缩)。
各种压缩方式与请求首部字段的Accept-Encoding一致。
Content-Language
Content-Language:zh-CN
会告知客户端,实体主体使用的自然语言(中文、英文)。
Content-Length
Content-Length: 548
该字段表明了实体主体部分的大小(单位是字节)。
Content-Location
Content-Location:http://www.xxx.com/xxxx
该字段给出与报文主体部分相对应的URI。和首部字段Location不同,其表示的是报文主体返回资源对应的URI。
Content-MD5
content-md5: PTuAV2ZimxfwDipIsHg/RA==
该字段的内容是 一串由MD5算法生成的值,其目的在于检查报文主体 在传输过程中是否保持完整,以及确认传输到达。
具体实现流程:
- 对报文主体执行MD5算法获得128位二进制数
- 通过Base64编码后将其写入字段Comtent-MD5(因为HTTP首部无法记录二进制值)
- 为了确保报文的有效性,接收方的客户端会对报文主体再执行一次相同的MD5算法,将其与字段值比较,即可判断报文主体是否准确了
采用这种方法是无法判断内容是否有偶发性改变和恶意篡改,原因在于:如果内容能被篡改,那么首部字段Content-MD5的值也可以被重新计算后被篡改,所以接收方是无法得知报文主体是否被篡改过的。
Content-Range
Content-Range:bytes 5001-10000/10000
针对范围请求,返回响应时使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。以字节为单位,表示当前发送部分及整个实体大小。
Content-Type
Content-Type: application/json
说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值。
Expires
Expires: Thu, 23 Jul 2020 11:57:40 GMT
该字段将资源失效的日期告诉客户端。
当首部字段Cache-Control有指定max-age指令时,比起Expires,会优先处理max-age指令。
Last-Modified
Last-Modified:Thu, 23 Jul 2020 11:57:40 GMT
指明资源最后一次修改的时间。
为Cookie服务的首部字段
Cookie用于管理服务器与客户端之间的状态。
它的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器把一些数据临时写入用户的计算机内,当用户访问时,可以通过通信方式取回之前发放的Cookie。
Set-Cookie首部字段
Set-Cookie: BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; max-age=86400; domain=.baidu.com; path=/
当服务器准备开始管理客户端的状态时,会事先告知各种信息。

expires属性
可以指定浏览器可发送Cookie的有效期,当省略expires属性时,其有效期就是浏览器会话(Session)时间段内,即浏览器被关闭之前。
一旦Cookie被服务器发送到客户端,服务器端就不存在可以显示删除Cookie的方法,但是可以覆盖过期的Cookie来实现对其的实质性删除操作。
path属性
可用于限制指定Cookie的发送范围的文件目录。
domain属性
指定域名,与结尾匹配一致,如:指定domain=example.com后,除了example.com以外,www.example.com、www2.example.com等都可以发送Cookie。
secure属性
用于限制Web页面仅再HTTPS安全连接时才可以发送Cookie。
HttpOnly属性
是Cookie的扩展功能,使JavaScript脚本不能获得Cookie,目的在于防止跨站脚本攻击(Cross-site scripting,XSS)对Cookie的信息窃取。
Cookie首部字段
Cookie:status=enable
该首部字段会告诉服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式来发送。
实施:Cookie: BAIDUID=8A669031A8473C10D237DEE69B24EC2D:FG=1; BIDUPSID=79FF44E17A2B908CEAD8750BE1A68B1E; PSTM=1590549482;
其他首部字段
HTTP首部字段是可以自行扩展的,所以在Web服务器和浏览器应用上会出现各种非标准的首部字段。
更多推荐


所有评论(0)