本文主要是介绍第六章HTTP首部,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第六章 HTTP首部
6.1 HTTP报文首部
HTTP协议的请求和响应报文中必定包含HTTP首部。**首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。**对于客户端用户来说,这些信息中的大部分内容都无须亲自查看。
报文首部由几个字段构成。
HTTP请求报文
请求中, HTTP报文由方法, URI, HTTP版本, HTTP首部字段等部分构成
例子:
POST /login HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Language: en-US,en;q=0.9
Referer: https://www.example.com/
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Connection: keep-aliveusername=johndoe&password=123
这个例子包括了HTTP请求报文的所有主要组成部分:
- 起始行(Start Line):
- 请求方法:
POST
- 请求目标(URI):
/login
- 协议版本:
HTTP/1.1
- 请求方法:
- 通用首部字段:
Connection: keep-alive
:指定保持连接。
- 请求首部字段:
Host: www.example.com
:指定请求的目标服务器的域名。User-Agent: ...
:标识客户端的用户代理。Accept: ...
:指定客户端可接受的媒体类型。Accept-Language: ...
:指定客户端可接受的自然语言。Referer: https://www.example.com/
:表示请求的来源,即上一个页面的URL。Content-Type: application/x-www-form-urlencoded
:指定请求正文的媒体类型。Content-Length: 25
:指定请求正文的长度。
- 空行(Blank Line):
- 用于分隔首部和实体。
- 实体(Entity):
- 包含请求正文的数据:
username=johndoe&password=123
- 包含请求正文的数据:
这个例子是一个使用POST方法的登录请求,其中包含了身份验证信息(用户名和密码)。请注意,实际的HTTP请求报文可能包含更多的首部字段,具体取决于客户端和服务器之间的需求。
HTTP响应报文
由HTTP版本, 状态码(数字和原因短语), HTTP首部字段三部分构成
例子:
HTTP/1.1 200 OK
Date: Tue, 02 Jan 2023 12:45:00 GMT
Server: Apache/2.4.38 (Unix)
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Connection: keep-alive<!DOCTYPE html>
<html>
<head><title>Example Page</title>
</head>
<body><p>Hello, World!</p>
</body>
</html>
解释:
-
起始行(Start Line):
- 协议版本:
HTTP/1.1
- 状态码:
200 OK
- 状态消息:
OK
- 协议版本:
-
通用首部字段:
Date: Tue, 02 Jan 2023 12:45:00 GMT
:指定响应创建的日期和时间。Connection: keep-alive
:指定保持连接。
-
响应首部字段:
Server: Apache/2.4.38 (Unix)
:包含关于服务器软件的信息。Content-Type: text/html; charset=utf-8
:指定响应正文的媒体类型和字符集。Content-Length: 1234
:指定响应正文的长度(以字节为单位)。
-
空行(Blank Line):
- 用于分隔首部和实体。
-
实体(Entity):
- 包含响应正文的HTML页面:
<!DOCTYPE html> <html> <head><title>Example Page</title> </head> <body><p>Hello, World!</p> </body> </html>
6.2 HTTP首部字段
6.2.1 HTTP首部字段传递重要信息
HTTP首部字段是构成HTTP 报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容
6.2.2 HTTP首部字段结构
HTTP首部字段由首部字段名和字段值构成, 中间用 : 分隔
例如, 在HTTP首部中以Content-Type这个字段来表示报文主题的对象类型
Content-Type: text/html
首部字段名为Content-Type, 字符串text/html是字段值
单个HTTP首部字段可以有多个值
Keep-Alive: timeout=15, max=100
若HTTP首部字段重复了会如何
当HTTP报文首部中出现了两个或两个以上具有相同首部字段名时会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。
6.2.3 4种HTTP首部字段类型
HTTP首部字段根据实际用途被分为以下4种类型
- 通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
- 请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
- 响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 实体首部字段(Entitv Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
6.2.4 HTTP/1.1首部字段一览
6.2.5 非HTTP/1.1首部字段
在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。还有Cookie、Set-Cookie和Content-Disposition等在其他 RFC 中定义的首部字段,它们的使用频率也很高。
这些非正式的首部字段统一归纳在RFC4229HTTPHeader FieldRegistrations中
6.2.6 End-to-end首部和Hop-by-hop首部
在HTTP报文的首部字段中,有两类重要的首部:End-to-End首部和Hop-by-Hop首部。它们指导了这些首部字段在传输过程中的行为和处理方式。
- End-to-End首部:
- 定义: End-to-End首部字段是指这些字段应该被发送的源端和最终接收的目标端保留,中间的任何代理服务器都不能修改或删除这些字段。
- 示例:
Content-Type
、Content-Length
等。 - 行为: 这些首部字段会在整个请求/响应链路上传递,并且在请求和响应的源和目标之间保留。代理服务器不能改变这些字段的语义或值。
- Hop-by-Hop首部:
- 定义: Hop-by-Hop首部字段是指这些字段在经过每一跳(每个代理服务器)时都需要进行处理,而不是在整个链路上都被保留。
- 示例:
Connection
、Proxy-Authorization
等。 - 行为: 这些字段只应该影响请求/响应的下一个节点,而不是整个链路。每个代理服务器都需要对这些字段进行处理,然后决定是否保留、修改或删除。
举例说明:
- End-to-End首部:
- 如果客户端在请求中包含
Content-Length
,那么这个字段的值将在整个链路上传递给服务器,以确保服务器能够正确地解析请求正文的长度。
- 如果客户端在请求中包含
- Hop-by-Hop首部:
- 如果客户端在请求中包含
Connection: close
,那么这个字段的效果只在与客户端相邻的下一个节点(例如代理服务器)上起作用,指示该节点在完成请求-响应后关闭连接,而不是将连接保持在活动状态。
- 如果客户端在请求中包含
HTTP/1.1规范定义了这两种首部字段的行为,以确保在多代理环境中能够正确传递信息,并且每个节点都能够按照正确的方式处理这些首部。
下面列举了HTTP/1.1中的逐跳首部字段。除这8个首部字段之外其他所有字段都属于端到端首部。
6.3 HTTP/1.1 通用首部字段
通用首部字段就是请求报文和响应报文都会使用的首部
6.3.1 Cache-Control
作用主要为操作缓存的工作机制
指令的参数可选, 多个指令通过 , 分隔**, 该指令可用于请求和响应**
Cache-Control指令一览
表示是否能缓存的指令
- public指令: 表示响应可以被任何缓存(包括代理服务器)存储。
- private指令: 表示响应仅仅可以被终端用户的浏览器缓存,而不允许被代理服务器缓存。
缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存
- no-cache指令
使用no-cache指令的目的是为了防止从缓存中返回过期的资源。客户端发送的请求中如果包含no-cache 指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存服务器必须把客户端请求转发给源服务器。
如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。
由服务器返回的响应中,若报文首部字段Cache-Control中对nocache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。
控制可执行缓存的对象的指令
- no-store指令
Cache-Control: no-store
当使用no-store指令时,暗示请求(和对应的响应)或响应中包含机密信息。因此,该指令规定缓存不能在本地存储请求或响应的任一部分
指定缓存期限和认证的指令
- s-maxage指令
Cache-Control: s-maxage=604800
s-maxage指令的功能和max-age指令的相同,它们的不同点是s-maxage指令只适用于供多位用户使用的公共缓存服务器。也就是说对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。另外,当使用s-maxage指令后,则直接忽略对 Expires首部字段及max-age指令的处理
- max-age指令
Cache-Control: max-age=604800
当客户端的请求包含max-age指令时, 如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。另外,当指定max-age值为0,那么缓存服务器通常需要将请求转发给源服务器
当服务器返回的响应中包含max-age 指令时,缓存服务器将不对资源的有效性再作确认,而max-age 数值代表资源保存为缓存的最长时间
应用HTTP/1.1版本的缓存服务器遇到同时存在Expires首部字段的情况时,会优先处理max-age指令,而忽略掉 Expires首部字段。而HTTP/1.0版本的缓存服务器的情况却相反,max-age指令会被忽略掉。
- min-fresh指令
Cache-Control: min-fresh=60
min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源。比如,当指定min-fresh为60秒后,过了60秒的资源都无法作为响应返回了
- max-stale指令
Cache-Control: max-stale=3600
使用max-stale可指示缓存资源,即使过期也照常接收。如果指令未指定参数值,那么无论经过多久,客户端都会接收响应如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale 指定的时间内,仍旧会被客户端接收。
- only-if-cached指令
Cache-Control: only-if-cached
使用only-if-cached 指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码504GatewayTimeout。
- must-revalidate指令
Cache-Control: must-revalidate
使用must-revalidate指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。
若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条504(GatewayTimeout)状态码。
另外,使用must-revalidate指令会忽略请求的max-stale指令(即使已经在首部使用了max-stale,也不会再有效果)。
- proxy-revalidate指令
Cache-Control: proxy-revalidate
类似于 must-revalidate
,但仅适用于共享缓存(代理服务器)。
proxy-revalidate指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性
- no-transform指令
Cache-Control: no-transform
使用no-transform指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。这样做可防止缓存或代理压缩图片等类似操作
Cache-Control扩展
cache-extension token
Cache-Control: private, community="UCI"
通过cache-extension标记(token),可以扩展Cache-Control首部字段内的指令。
如上例,**Cache-Control首部字段本身没有community这个指令。借助extension tokens实现了该指令的添加。**如果缓存服务器不能理解community这个新指令,就会直接忽略。因此,extension tokens仅对能理解它的缓存服务器来说是有意义的。
6.3.2 Connection
Connection首部字段具备如下两个作用
- 控制不再转发给代理的首部字段
- 管理持久连接
控制不再转发给代理的首部字段
Connection: 不再转发的首部字段
在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段(即Hop-by-hop首部)。
管理持久连接
Connection: close
HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为 Close。
Connection: kepp-Alive
HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。
6.3.3 Date
首部字段Date表明创建HTTP报文的日期和时间
HTTP/1.1协议使用在RFC1123中规定的日期时间的格式
Date: Tue, 03 Jul 2012 04:40:59 GMT
之前的HTTP协议使用的RFC850定义的格式:
Date: Tue, 03-Jul-12 04:40:59 GMT
此外, 还有一种与C标准库内的asctime()函数的输出格式一致
Date: Tue Jul 03 04:40:59 2012
6.3.4 Pragma
Pragma是HTTP/1.1之前版本的历史遗留字段, 仅作为与HTTP/1.0的向后兼容而定义
Pragma: no-cache
在早期的HTTP/1.0规范中,Pragma
被用于向客户端和服务器传递指令,通常用于控制缓存行为。一个常见的例子是 Pragma: no-cache
,**表示不使用缓存,必须从原始服务器请求资源。**然而,随着HTTP/1.1的引入和其他首部字段(如 Cache-Control
的广泛使用),Pragma
的使用逐渐减少。
所有的中间服务器如果都能以HTTP/1.1为基准,那直接采用Cache-Control:no-cache 指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的HTTP协议版本却是不现实的。因此,发送的请求会同时含有下面两个首部字段。
6.3.5 Trailer
Trailer
是HTTP报文的通用首部字段之一,用于在报文尾部(实体主体后)包含一些额外的首部字段信息。通常,Trailer
首部字段在传输编码(Transfer-Encoding)为 chunked 的情况下使用。
在传输编码为 chunked 的情况下,HTTP报文的实体主体被分成一系列的数据块,每个数据块包含了数据本身和一组首部字段,这些首部字段包含在 Trailer
首部字段中指定的字段列表中。
示例:
HTTP/1.1 200 OK
Date: Tue, 10 Jan 2023 15:30:00 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Trailer: Content-MD525
This is the first chunk
1A
and this is the second one
0
Content-MD5: qea5zdb9tA3nxZGJlT+JfA==
解释:
Transfer-Encoding: chunked
表示报文的实体主体使用分块传输编码。Trailer: Content-MD5
表示在报文的尾部可能包含一个名为Content-MD5
的首部字段。- 实体主体被分成两个数据块,每个数据块都包含了数据本身和对应的
Content-MD5
首部字段。 - 最后的
0
表示数据块的结束(分块长度为0),而紧随其后的Content-MD5
首部字段包含了整个实体主体的MD5校验和。
6.3.6 Transfer-Encoding
Transfer-Encoding
是HTTP报文的通用首部字段之一,用于**指定在传输过程中对报文主体的编码方式。**它定义了在传输报文主体时如何对其进行编码,以及在接收端如何解码。这主要用于支持在传输过程中对大文件或流进行分块传输(chunked transfer),以及对报文主体进行压缩等操作。
一些常见的 Transfer-Encoding
值包括:
- chunked:
- 表示报文主体被分割成一系列的数据块(chunks),每个数据块都包含数据的长度以及数据本身。这允许在接收端逐个解码,而不需要提前知道报文主体的总长度。
- gzip:
- 表示报文主体使用 Gzip 压缩进行编码。这有助于减小传输的数据量,提高传输效率。
- deflate:
- 表示报文主体使用 Deflate 压缩进行编码。
- identity:
- 表示报文主体没有经过编码,是未经过任何变化的原始数据。
HTTP/1.1 200 OK
Date: Tue, 10 Jan 2023 15:30:00 GMT
Content-Type: text/plain
Transfer-Encoding: chunked25
This is the first chunk
1A
and this is the second one
0
在上述示例中,Transfer-Encoding: chunked
表示报文主体使用分块传输编码。后续的数据块以十六进制表示的长度开头,并在每个数据块之后以 0
表示结束。
需要注意的是,Transfer-Encoding
可以由多个编码方式组合使用,以逗号分隔。例如,Transfer-Encoding: gzip, chunked
表示报文主体首先经过 Gzip 压缩,然后再进行分块传输。
6.3.7 Upgrade
首部字段**Upgrade 用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,**其参数值可以用来指定一个完全不同的通信协议。
示例:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
在这个例子中,客户端通过使用 Upgrade: websocket
表示希望升级到WebSocket协议。Connection: Upgrade
表示当前连接是为了升级而存在的。其他首部字段(例如 Sec-WebSocket-Key
和 Sec-WebSocket-Version
)是用于WebSocket协议握手的信息。
服务器的响应可能如下所示:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
在这个例子中,服务器通过 HTTP/1.1 101 Switching Protocols
表示成功升级到WebSocket协议。Upgrade: websocket
和 Connection: Upgrade
指示了升级。Sec-WebSocket-Accept
是服务器生成的一个响应WebSocket握手挑战的验证密钥。
总体而言,Upgrade
首部字段为客户端和服务器提供了一种协商升级到更高层次协议的方式,它常用于实现从HTTP到其他协议(如WebSocket)的切换。
6.3.8 via
Via
是HTTP报文的通用首部字段之一,用于追踪客户端和中间服务器之间的请求-响应链路。它包含了一系列代理服务器或网关的信息,表示请求或响应经过了哪些中间节点。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
Via: 1.1 proxy1.example.com, 1.1 proxy2.example.com
在上述示例中,Via
首部字段包含了两个代理服务器的信息:proxy1.example.com
和 proxy2.example.com
。这表示请求经过了这两个代理服务器。
多个代理服务器的信息在 Via
首部字段中用逗号分隔。每个元素都包含了代理服务器的版本号和服务器的主机名或IP地址。
Via
首部字段的主要用途是在请求和响应中识别出HTTP流经的路径,有助于调试和监控HTTP通信。它也可以用于检测潜在的代理环路(proxy loops)。
需要注意的是,Via
首部字段是按照数据流的方向添加的。在请求中,Via
字段的值是从客户端到服务器的流程;在响应中,Via
字段的值是从服务器到客户端的流程。由于代理可能会在请求和响应的过程中添加或修改 Via
字段,所以最终的 Via
字段值可能包含了整个通信链路的信息。
6.3.9 Warning
Warning
是HTTP报文的通用首部字段之一,用于提供有关消息的警告信息。Warning
首部字段允许服务器或代理向客户端提供有关可能出现问题的消息的警告。
示例:
HTTP/1.1 200 OK
Date: Tue, 10 Jan 2023 15:30:00 GMT
Server: Apache/2.4.38 (Unix)
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Warning: 199 Miscellaneous warning
在上述示例中,Warning: 199 Miscellaneous warning
表示服务器在处理请求时发生了一般性的警告,代码为199。警告信息是一个文本字符串,提供了更详细的描述。
Warning
首部字段的结构如下:
- 警告码(Warning Code): 一个3位的警告码,表示警告的类型。例如,
199
表示Miscellaneous warning。 - 主机(Host): 可选项,表示警告是由哪个服务器生成的。
- 警告文本(Warning Text): 提供对警告的更详细的描述。
多个 Warning
首部字段可以以逗号分隔,表示多个警告。
**Warning
首部字段通常用于向客户端提供有关可能导致问题的信息,以便客户端能够更好地处理或展示警告。**例如,可能的应用场景包括缓存的相关问题、连接问题等。
需要注意的是,Warning
首部字段是可选的,而且并不是所有的HTTP响应都包含这个字段
警告码:
6.4 请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容
6.4.1 Accept
Accept
是HTTP请求报文中的首部字段之一,用于指定客户端能够接受的媒体类型(MIME类型)。这样服务器就可以根据客户端的需求来选择合适的响应内容类型。Accept
首部字段的值是一个逗号分隔的媒体类型列表,每个媒体类型可以包含一个可选的优先级。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
在上述示例中,Accept
首部字段表示客户端愿意接受的媒体类型有:text/html
、application/xhtml+xml
、application/xml
(优先级为0.9),以及任意其他类型(*/*
,优先级为0.8)。
text/html
: HTML文本application/xhtml+xml
: XHTML文档application/xml
: 通用的XML文档*/*
: 任意类型
每个媒体类型的优先级是可选的,默认为1。较高优先级的媒体类型在选择响应内容时会被优先考虑。
需要注意的是,Accept
首部字段的内容通常由浏览器生成,它告诉服务器希望接收的内容类型。服务器可以根据这个信息来选择最适合客户端的响应类型。如果服务器无法提供客户端希望接收的内容类型,通常会返回406 Not Acceptable状态码。
媒体类型的例子:
6.4.2 Accept-Charset
Accept-Charset
是HTTP请求报文中的首部字段之一,**用于指定客户端能够接受的字符集(字符编码)。**服务器可以使用这个信息来选择合适的字符集,以便返回符合客户端要求的响应。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
Accept-Charset: utf-8, iso-8859-1;q=0.7, *;q=0.5
在上述示例中,Accept-Charset
首部字段表示客户端愿意接受的字符集有:utf-8
、iso-8859-1
(优先级为0.7),以及任意其他字符集(*
,优先级为0.5)。
utf-8
: Unicode字符集,通常用于支持多语言文本。iso-8859-1
: ISO-8859-1字符集,也称为Latin-1,用于西欧语言。
每个字符集的优先级是可选的,默认为1。较高优先级的字符集在选择响应内容时会被优先考虑。
服务器可以根据这个信息来选择最适合客户端的字符集,以确保返回的响应可以正确解析和显示。如果服务器无法提供客户端希望接收的字符集,通常会返回406 Not Acceptable状态码。
6.4.3 Accept-Encoding
Accept-Encoding
是HTTP请求报文中的首部字段之一,用于指定客户端能够接受的内容编码方式。这样服务器可以使用合适的编码方式来传输响应,以减小传输的数据量,提高传输效率。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, deflate, br
在上述示例中,Accept-Encoding
首部字段表示客户端愿意接受的内容编码方式有:gzip
、deflate
和 br
(Brotli压缩算法)。
gzip
: 使用Gzip压缩算法进行编码。deflate
: 使用Deflate压缩算法进行编码。br
: 使用Brotli压缩算法进行编码。
如果服务器支持客户端希望接受的编码方式,它可以在响应中使用相应的编码方式进行内容压缩。这有助于减小传输的数据量,提高传输效率。
每个编码方式的优先级是可选的,默认为1。较高优先级的编码方式在选择响应内容时会被优先考虑。
需要注意的是,如果客户端不愿意接受任何编码方式,可以将 Accept-Encoding
设置为空值或省略。服务器在这种情况下会返回未经过任何编码的原始内容。
6.4.4 Accept-Language
Accept-Language
是HTTP请求报文中的首部字段之一,用于指定客户端能够接受的自然语言(例如,语言和区域设置)。这样服务器就可以根据客户端的首选语言来选择最适合的响应。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
Accept-Language: en-US,en;q=0.5
在上述示例中,Accept-Language
首部字段表示客户端愿意接受的语言有:en-US
(英语,美国地区)和 en
(通用英语)。后者的优先级为0.5,表示相对较低的优先级。
6.4.5 Authorization
首部字段Authorization是用来告知服务器,用户代理的认证信息证书值)。通常,**想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,把首部字段Authorization 加人请求中。**共用缓存在接收到含有Authorization首部字段的请求时的操作处理会略有差异
示例:
GET /path/to/protected/resource HTTP/1.1
Host: www.example.com
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
在上述示例中,Authorization
首部字段包含了一个Base64编码的字符串,形式为 Basic [credentials]
,表示使用基本身份验证。具体的 credentials
是由用户名和密码组成,并用冒号(:
)连接后再进行Base64编码的。
- 用户名:
Aladdin
- 密码:
open sesame
经过Base64编码后,YWxhZGRpbjpvcGVuc2VzYW1l
就是身份验证凭据。
6.4.6 Expect
Expect
是HTTP请求报文的首部字段之一,**用于指示客户端期望服务器在处理请求时采取的行为。**常见的用法是用于要求服务器是否愿意接受包含请求体的请求,以及如何处理这些请求。
示例:
POST /path/to/resource HTTP/1.1
Host: www.example.com
Expect: 100-continue
在上述示例中,Expect: 100-continue
表示客户端期望服务器返回状态码 100 Continue
,这是一种用于请求体较大的情况下的优化机制。客户端在发送请求体之前会先发送包含 Expect: 100-continue
的请求头,如果服务器能够处理这个请求并愿意接受请求体,就会返回 100 Continue
状态码,然后客户端再发送请求体。
其他的 Expect
值还包括:
Expect: 100-continue
: 上述提到的,用于请求体较大的情况,进行状态码的预检。Expect: 101 Upgrade
: 表示客户端希望升级协议。常用于WebSocket协议的升级请求。
如果服务器无法满足 Expect
字段的要求,通常会返回 417 Expectation Failed
状态码。
需要注意的是,虽然 HTTP 规范中定义了 Expect
头部,但在实际应用中,它的使用相对较少,而且并不是所有的服务器都会正确处理它。因此,在使用 Expect
头部时需要谨慎,并确保服务器能够正确处理相关的行为。
6.4.7 From
From
是HTTP请求报文的首部字段之一,**用于包含发送请求的用户的电子邮件地址信息。**该字段通常用于提供一个联系点,让服务器或资源的所有者知道请求的来源。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
From: user@example.com
在上述示例中**,From: user@example.com
表示发送请求的用户的电子邮件地址为 user@example.com
。**
需要注意的是,From
首部字段的使用并不常见,而且并非所有的服务器都会处理它。在很多情况下,身份和联系信息更倾向于使用其他更安全和可靠的机制,比如身份验证和授权头部字段(如 Authorization
)。因此,开发者在使用 From
时需要谨慎,确保它符合实际需求并且不会引起潜在的安全问题。
6.4.8 Host
首部字段Host 会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段
首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段 Host 必须存在的意义。
请求被发送至服务器时,请求中的主机名会用IP 地址直接替换解决。但如果这时,相同的IP地址下部署运行着多个域名,那么服务器就会无法理解究竟是哪个域名对应的请求。因此,就需要使用首部字段Host来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。
6.4.9 If-Match
形如If-xxx这种形式的请求首部字段, 都可以称之为条件请求, 服务器在接收到这种请求后, 只有判断条件为真时, 才会执行请求
首部字段If-Match,属附带条件之一,它会告知服务器匹配资源所用的实体标记(ETag)值。这时的服务器无法使用弱ETag值。
服务器会比对If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,则返回状态码412 Precondition Failed 的响应。还可以使用星号(*)指定f-Match的字段值。针对这种情况,服务器将会忽略 ETag的值,只要资源存在就处理请求
6.4.10 If-Modified-Since
首部字段If-Modified-Since,属附带条件之一,它会告知服务器若If-Modified-Since字段值早于资源的更新时间,则希望能处理该请求, 而在指定If-Modified-Since字段值的日期时间之后,如果请求的资源都没有过更新,则返回状态码304 Not Modified 的响应
If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段Last-Modified来确定。
6.4.11 If-None-Match
首部字段If-None-Match属于附带条件之一。它和首部字段IfMatch作用相反。用于指定If-None-Match字段值的实体标记(ETag值与请求资源的ETag不一致时,它就告知服务器处理该请求。
在GET或HEAD方法中使用首部字段If-None-Match可获取最新的资源。因此,这与使用首部字段If-Modified-Since时有些类似。
6.4.12 If-Range
首部字段If-Range属于附带条件之一。它告知服务器若指定的If-Range字段值(ETag值或者时间)和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源
下面我们思考一下不使用首部字段If-Range发送请求的情况。服务器端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当然,范围请求作为前提是无效的。这时,服务器会暂且以状态码412Precondition Failed作为响应返回,其目的是催促客户端再次发送请求这样一来,与使用首部字段If-Range 比起来,就需要花费两倍的功夫
6.4.13 If-Unmodified-Since
首部字段If-Unmodified-Since和首部字段If-Modified-Since的作用相反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码412Precondition Failed作为响应返回。
6.4.14 Max-Forwards
通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards的值减1后重新赋值。当服务器接收到Max-Forwards值为0的请求时,则不再进行转发,而是直接返回响应。
使用HTTP协议通信时,请求可能会经过代理等多台服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器返回的响应了。对此,我们无从可知。
可以灵活使用首部字段Max-Forwards,针对以上问题产生的原因展开调查。由于当Max-Forwards 字段值为0时,服务器就会立即返回响应,由此我们至少可以对以那台服务器为终点的传输路径的通信状况有所把握
6.4.15 Proxy-Authorization
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息这个行为是与客户端和服务器之间的HTTP访问认证相类似的,不同之处在于,认证行为发生在客户端与代理之间。客户端与服务器之间的认证使用首部字段Authorization可起到相同作用。
6.4.16 Range
对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围。上面的示例表示请求获取从第5001字节至第10000字节的资源。
接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码为206Partial Content的响应。无法处理该范围请求时,则会返回状态码2000K的响应及全部资源。
6.4.17 Referer
Referer
是HTTP请求报文的首部字段之一,用于**指示请求的来源,即当前请求是从哪个页面或资源跳转过来的。**这个字段提供了一种追踪请求来源的机制。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
Referer: https://www.previous-site.com/page
在上述示例中,Referer: https://www.previous-site.com/page
表示当前请求是从 https://www.previous-site.com/page
页面跳转而来的。
Referer
字段对于网站分析、日志记录和安全性方面都有一定的用途。例如,网站可以使用 Referer
信息来分析用户的访问路径,了解用户是如何导航到当前页面的。但需要注意的是,Referer
是由客户端提供的,因此可以被用户修改或省略,不应完全信任其内容。
有时为了隐私和安全原因,用户代理(浏览器)会限制或省略 Referer
头部。例如,当从一个安全(HTTPS)站点跳转到非安全(HTTP)站点时,一些浏览器可能会省略 Referer
头部,以减少信息泄漏的风险。这种情况下,服务器可能会收到一个空白的 Referer
或者不包含 Referer
头部的请求。
6.4.18 TE
TE
是HTTP请求报文的首部字段之一,**用于指定客户端支持的传输编码方式(Transfer-Encoding)。**传输编码主要用于在消息传输过程中对实体主体进行编码,以提高传输效率或满足特定需求。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
TE: gzip, deflate
在上述示例中,TE: gzip, deflate
表示客户端支持使用 Gzip 或 Deflate 这两种传输编码方式进行压缩。服务器可以根据客户端的支持情况,选择其中一种编码方式对响应实体进行压缩,从而减小传输的数据量。
6.4.19 User-Agent
User-Agent
是HTTP请求报文的首部字段之一,用于标识发送请求的用户代理(User Agent),通常是指浏览器或其他客户端程序的标识信息。这个字段允许服务器了解客户端的软件、操作系统、版本和其他相关信息,从而根据需要调整或定制响应。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
在上述示例中,User-Agent
字段包含了一个典型的浏览器标识,表示请求是由 Chrome 浏览器在 Windows 操作系统上发起的。
服务器可以使用 User-Agent
信息来根据不同的客户端类型,提供不同的响应或资源。例如,网站可能根据用户使用的浏览器类型和版本,提供特定于该浏览器的样式表或功能。但需要注意的是,User-Agent
可以被用户修改,因此它不是可信任的客户端身份标识。
在某些情况下,网站可能会使用 User-Agent
字段来进行浏览器嗅探,以适应不同的浏览器或平台。然而,现代的开发实践通常更推荐使用 feature detection(功能检测)而非 user agent sniffing(浏览器嗅探),以确保更稳定和可维护的网站。
6.5 响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段
6.5.1 Accept-Ranges
Accept-Ranges
是HTTP响应报文的首部字段之一,用于指示服务器是否支持对资源的范围请求,以及支持的范围单位(单位是字节,即 bytes)。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 00:00:00 GMT
Content-Type: text/html
Accept-Ranges: bytes
在上述示例中,Accept-Ranges: bytes
表示服务器支持对资源进行范围请求,并且范围的单位是字节。这意味着客户端可以通过发送带有 Range
头部字段的请求来请求资源的特定范围,而不必下载整个资源。
如果服务器不支持范围请求,通常会使用 Accept-Ranges: none
来表示。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 00:00:00 GMT
Content-Type: text/plain
Accept-Ranges: none
在上述示例中,Accept-Ranges: none
表示服务器不支持对资源进行范围请求,客户端只能获取整个资源,而不能请求资源的部分内容。
**范围请求是通过客户端发送带有 Range
头部字段的请求来实现的,服务器通过 Content-Range
头部字段来指示返回的是请求范围的响应。**支持范围请求对于大文件的断点续传和并行下载等场景非常有用。
6.5.2 Age
Age
是HTTP响应报文的首部字段之一,用于指示在代理服务器上缓存的响应从原始服务器生成以来经过的时间,以秒为单位。这个字段通常用于缓存控制和调试。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Cache-Control: max-age=3600
Age: 1800
在上述示例中,Age: 1800
表示这个响应自从在原始服务器生成之后,已经被代理缓存了1800秒(30分钟)。
该字段有助于客户端和其他代理了解响应的新鲜度和缓存时长。在一些缓存环境中,代理服务器可能会在缓存中存储响应,并通过 Age
字段来表示这个响应在缓存中存在的时间。
需要注意的是,Age
字段是由代理服务器添加的,并且可能会受到时钟不同步等因素的影响,因此它并不总是完全准确。当客户端或代理服务器收到响应时,会使用本地时钟和 Date
头部字段中的日期信息来计算 Age
字段的值。
6.5.3 ETag
ETag
(Entity Tag)是HTTP响应报文的首部字段之一,用于标识资源的版本信息。它通常是服务器根据资源内容生成的唯一标识符,用于支持缓存验证和条件请求。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
ETag: "abc123"
在上述示例中,ETag: "abc123"
表示这个响应对应的资源版本标识是 “abc123”。客户端在之后的请求中可以使用这个标识符,通过条件请求来检查资源是否发生了变化,以便决定是否从缓存中获取数据。
客户端可以在后续的请求中通过 If-None-Match
头部字段将之前获取的 ETag
发送给服务器,询问服务器资源是否发生了变化。如果资源未发生变化,服务器可能会返回 304 Not Modified
状态码,表示客户端的缓存是最新的,无需重新传输资源。
示例:
GET /path/to/resource HTTP/1.1
Host: www.example.com
If-None-Match: "abc123"
ETag
是一种常用的缓存验证机制,与其他条件请求相关的头部字段(如 Last-Modified
)一起,可以帮助客户端和服务器有效地管理缓存和提高性能。
- 强ETag值
无论实体发生多么细微的变化都会改变其值
ETag: "usagi-1234"
- 弱ETag值
弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
ETag: W/"usagi-1234"
6.5.4 Location
Location
是HTTP响应报文的首部字段之一,用于指示客户端应该重定向到的URI(统一资源标识符)。通常,Location
首部字段会在服务器返回的响应中用于告知客户端资源的新位置或新的URI。
示例:
httpCopy codeHTTP/1.1 302 Found
Location: https://www.example.com/new-location
在上述示例中,Location: https://www.example.com/new-location
表示客户端请求的资源已经被移到了 https://www.example.com/new-location
,并且客户端应该向这个新的URI重新发起请求。
常见的HTTP状态码与 Location
结合使用的有:
- 302 Found(临时重定向): 资源被临时移动,将来的请求仍然应该使用原始URI。
- 301 Moved Permanently(永久重定向): 资源被永久移动,将来的请求应该使用新的URI。
- 307 Temporary Redirect(临时重定向): 与302类似,表示资源被临时移动,将来的请求仍然应该使用原始URI。
- 308 Permanent Redirect(永久重定向): 与301类似,表示资源被永久移动,将来的请求应该使用新的URI。
当客户端收到包含 Location
头部字段的响应时,它会自动重定向到新的URI。这对于处理需要重定向的情况,如网页移动、登录成功后跳转等,非常有用。
6.5.5 Proxy-Authenticate
Proxy-Authenticate
是HTTP响应报文的首部字段之一,用于表示客户端必须使用代理认证进行访问。当客户端请求代理服务器时,如果代理服务器要求进行身份验证,就会通过 Proxy-Authenticate
字段来通知客户端应该使用的认证方法。
HTTP/1.1 407 Proxy Authentication Required
Date: Wed, 29 Dec 2023 12:00:00 GMT
Proxy-Authenticate: Basic realm="Proxy Zone"
在上述示例中,Proxy-Authenticate: Basic realm="Proxy Zone"
表示代理服务器要求进行基本身份验证(Basic Authentication),并提供了一个领域名为 “Proxy Zone” 的域(realm),以提示客户端提供合适的凭据。
客户端在收到这个响应后,应该根据所要求的认证方法提供相应的凭据,并通过 Proxy-Authorization
字段将凭据发送给代理服务器。
GET /path/to/resource HTTP/1.1
Host: www.example.com
Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
在上述示例中,Proxy-Authorization
字段包含了使用基本身份验证提供的凭据,其中 YWxhZGRpbjpvcGVuc2VzYW1l
是用户名和密码经过Base64编码的字符串。
需要注意的是,这个过程仅在代理服务器要求进行身份验证时才会发生,否则通常不需要在请求中包含 Proxy-Authorization
字段。
6.5.6 Retry-After
Retry-After
是HTTP响应报文的首部字段之一,用于指示客户端在多久之后可以重试对相同资源的请求。这个字段通常用于表示服务器的过载情况或维护,以及告知客户端应该在多久之后重新尝试访问资源。主要配合状态码503 Service Unavailable 响应,或3xx Redirect 响应一起使用。
Retry-After
的值可以有两种形式:
-
HTTP-date 格式:
Retry-After: Fri, 31 Dec 2023 12:00:00 GMT
在这种情况下,
Retry-After
表示客户端应该在指定的日期和时间之后重试请求。 -
秒数格式:
Retry-After: 3600
在这种情况下,
Retry-After
表示客户端应该在指定的秒数之后重试请求。
6.5.7 Server
Server
是HTTP响应报文的首部字段之一,用于指示服务器使用的软件和版本信息。该字段告诉客户端正在与之通信的服务器的标识。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Server: Apache/2.4.38 (Unix) OpenSSL/1.1.1d
在上述示例中,Server: Apache/2.4.38 (Unix) OpenSSL/1.1.1d
表示服务器正在使用 Apache 软件的版本号为 2.4.38,运行在 Unix 操作系统,并使用 OpenSSL 版本 1.1.1d。
虽然 Server
头部字段对于客户端和开发者来说提供了一些关于服务器的信息,但在一些安全性方面,有时候会选择限制或者模糊这个信息,以减少攻击者对系统的了解。
Server
字段对于网站性能分析和服务器管理来说是有用的,但需要小心,确保不向潜在的攻击者透露过多关于服务器的详细信息,以提高安全性。
6.5.8 Vary
Vary
是HTTP响应报文的首部字段之一,用于指示缓存机制需要考虑的请求头部字段,以决定响应是否适用于特定的缓存。这个字段通常在服务器返回的响应中,特别是对于支持内容协商的资源。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Vary: Accept-Encoding, User-Agent
在上述示例中,Vary: Accept-Encoding, User-Agent
表示对于这个资源的缓存,需要考虑客户端的 Accept-Encoding
(表示支持的内容编码方式,如gzip)和 User-Agent
(表示客户端的用户代理标识,如浏览器类型和版本)这两个请求头部字段的值。
当代理服务器或浏览器进行缓存时,会考虑 Vary
字段中列举的请求头部字段的值,以确保缓存的响应适用于相同的请求头部字段值。如果请求头部字段的值不匹配,缓存将不会使用已有的响应,而是向服务器请求新的响应。
Vary
头部字段对于内容协商和缓存管理是非常重要的。它允许服务器根据请求头部字段的变化提供不同版本的资源,并确保缓存系统能够正确处理这些变化。
6.5.9 WWW-Authenticate
WWW-Authenticate
是HTTP响应报文的首部字段之一,用于**指示客户端必须使用认证机制来访问受保护的资源。**当服务器返回需要进行身份验证的响应时,通常会使用 WWW-Authenticate
字段来告知客户端应该使用的认证方法和领域(realm)。
示例:
HTTP/1.1 401 Unauthorized
Date: Wed, 29 Dec 2023 12:00:00 GMT
WWW-Authenticate: Basic realm="Example"
在上述示例中,WWW-Authenticate: Basic realm="Example"
表示客户端必须使用基本身份验证(Basic Authentication)来访问受保护的资源,并提供了一个领域名为 “Example” 的域(realm),以提示客户端提供合适的凭据。
客户端在收到这个响应后,应该使用 Authorization
字段提供相应的凭据,并重新发起请求。
httpCopy codeGET /path/to/resource HTTP/1.1
Host: www.example.com
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
在上述示例中,Authorization
字段包含了使用基本身份验证提供的凭据,其中 YWxhZGRpbjpvcGVuc2VzYW1l
是用户名和密码经过Base64编码的字符串。
**WWW-Authenticate
头部字段是与 401 Unauthorized
状态码一起使用的,用于指示客户端需要进行身份验证以获得访问权限。**它可以指定多个认证方法,客户端可以根据自身支持的方法选择合适的认证方式。
6.6 实体首部字段
实体首部字段是HTTP报文中**用于描述实体主体的元数据的字段。它们提供了有关实体主体的一些信息,如数据类型、长度、语言等。**实体主体是HTTP消息中包含的实际数据,可以是文本、图像、视频等。
6.6.1 Allow
Allow
是HTTP响应报文的首部字段之一,用于指示对某个资源所支持的HTTP方法。通常,它会在服务器成功处理对资源的请求后返回,以告知客户端在该资源上可以使用的HTTP方法。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Allow: GET, HEAD, POST
在上述示例中,Allow: GET, HEAD, POST
表示对于该资源,客户端可以使用的HTTP方法包括GET、HEAD和POST。
客户端可以根据 Allow
头部字段来了解服务器允许使用哪些HTTP方法,从而进行后续的请求操作。这对于实现RESTful API和对资源的合理使用非常重要。
需要注意的是,Allow
头部字段通常出现在成功的HTTP响应中(例如,状态码为200或204),以提供关于资源允许使用的HTTP方法的信息。
6.6.2 Content-Encoding
Content-Encoding
是HTTP响应报文的首部字段之一,用于指定对实体主体执行的内容编码方式。该字段通常在服务器对响应实体进行压缩或编码时使用,以减小传输的数据量,提高性能。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Content-Encoding: gzip
在上述示例中,Content-Encoding: gzip
表示响应实体主体使用gzip压缩编码。客户端在接收到这个响应后,会根据 Content-Encoding
的值来解压缩实体主体,以获取原始的内容。
6.6.3 Content-Language
Content-Language
是HTTP响应报文的首部字段之一,用于指定实体主体所使用的自然语言或语言列表。该字段告诉客户端响应的内容使用的语言,以便客户端能够正确处理和呈现文本内容。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Content-Language: en-US
在上述示例中,Content-Language: en-US
表示响应实体主体使用的语言是美式英语(English, United States)。
如果一个资源可以使用多种语言表示,Content-Language
字段可以包含多个语言标签,使用逗号分隔,例如:
Content-Language: en-US, fr-FR
客户端可以使用这个信息来选择最适合用户首选语言的版本,或者进行其他语言相关的处理。这对于多语言网站和国际化的应用程序非常有用。
需要注意的是,Content-Language
只提供了一种提示,告诉客户端响应主体的语言,但它并不强制客户端或代理使用这种语言进行显示或处理。
6.6.4 Content-Length
Content-Length
是HTTP报文的首部字段之一,用于指定实体主体的长度,以字节为单位。该字段通常出现在HTTP响应报文中,以告知客户端实体主体的大小,也可以出现在HTTP请求报文中,指定请求主体的大小。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Content-Length: 1234
在上述示例中,Content-Length: 1234
表示响应实体主体的长度是1234字节。
- 客户端在接收到带有
Content-Length
字段的响应后,可以使用这个信息来正确地读取和处理实体主体。如果实体主体的长度与Content-Length
指定的长度不一致,可能会导致数据截断或解析错误。 - 需要注意的是,对于使用了分块传输编码(Chunked Transfer-Encoding)的响应,
Content-Length
字段可能会被省略,因为分块传输编码的特性是不需要提前知道整个实体主体的大小。 - 在使用编码传输(例如gzip、deflate等)时,通常不应该使用
Content-Length
首部字段。原因是,内容编码会改变实体主体的大小,而Content-Length
是指定实体主体未编码时的大小。
6.6.5 Content-Location
Content-Location
是HTTP响应报文的首部字段之一,用于指定与响应实体主体相关的资源的位置。这个字段表示客户端可以在给定的URI处找到与实体主体相关的资源。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Content-Location: /path/to/resource
在上述示例中,Content-Location: /path/to/resource
表示响应实体主体对应的资源可以在 /path/to/resource
这个URI处找到。
Content-Location
通常用于标识实际提供响应的资源的位置,尤其是在内容协商或重定向的情况下。例如,当一个请求引起了内容协商,服务器可能返回的实体主体与请求的URI不同,这时可以使用 Content-Location
来指示实际资源的位置。
需要注意的是,Content-Location
不同于 Location
头部字段。Location
用于指示客户端应该重定向到的新的URI,而 Content-Location
用于指示与响应实体主体相关的资源的位置。
6.6.6 Content-MD5
Content-MD5
是HTTP报文的首部字段之一,用于提供实体主体的MD5摘要。MD5(Message Digest Algorithm 5)是一种用于产生数据的哈希值的算法,通常用于验证数据的完整性。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/plain
Content-Length: 1024
Content-MD5: d41d8cd98f00b204e9800998ecf8427e
在上述示例中,Content-MD5: d41d8cd98f00b204e9800998ecf8427e
表示实体主体的MD5摘要是 d41d8cd98f00b204e9800998ecf8427e
。客户端可以使用这个摘要来验证实体主体的完整性,确保在传输过程中没有发生数据损坏或篡改。
需要注意的是,MD5算法在现代密码学中不再被认为是安全的,因此 Content-MD5
主要用于验证数据完整性而不是安全性。在一些安全敏感的应用中,可能会使用更强大的哈希算法,如SHA-256,来提供更高的安全性。
如果服务器提供了 Content-MD5
,客户端在接收到实体主体后可以计算实体主体的MD5摘要,并将其与 Content-MD5
字段的值进行比较,以确保数据的完整性。
6.6.7 Content-Range
Content-Range
是HTTP响应报文的首部字段之一,用于指定响应实体主体的范围(Range)以及整个实体主体的总体大小。这通常用于支持断点续传或部分内容传输。
示例:
HTTP/1.1 206 Partial Content
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: video/mp4
Content-Range: bytes 5000-9999/20000
Content-Length: 5000
在上述示例中,**Content-Range: bytes 5000-9999/20000
表示响应实体主体的范围是5000到9999字节,总体大小为20000字节。**这样的响应通常是支持断点续传的服务器在客户端请求某个资源的部分内容时返回的。
Content-Range
字段的值的格式为 unit range-start-end/total
,其中:
unit
表示范围的单位,通常为 “bytes”。range-start
表示范围的起始字节位置。range-end
表示范围的结束字节位置。total
表示整个实体主体的总体大小。
如果 Content-Range
字段出现在完整的响应中而非部分响应中,range-start-end
可以被省略,只保留 unit total
。
需要注意的是,当服务器返回部分内容时,还应该包含 206 Partial Content
状态码,以明确表示这是一个部分响应。
6.6.8 Content-Type
Content-Type
是HTTP报文的首部字段之一,用于指定实体主体的媒体类型(Media Type)。该字段告诉客户端如何解释响应的实体主体,并决定如何处理或显示该内容。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html; charset=utf-8
在上述示例中,Content-Type: text/html; charset=utf-8
表示实体主体是HTML文档,字符集为UTF-8编码。这样,客户端就知道如何正确地解析和显示响应的实体主体。
Content-Type
的值通常由两部分组成:
- 媒体类型(Media Type): 表示实体主体的大类,例如"text"表示文本,"image"表示图像,"application"表示应用程序数据等。
- 字符集(Character Set): 用于指定文本编码的字符集,例如"utf-8"表示UTF-8编码。
常见的媒体类型包括:
text/html
:HTML文档text/plain
:纯文本application/json
:JSON数据image/jpeg
:JPEG图像audio/mp3
:MP3音频
Content-Type
是一个关键的HTTP头部字段,确保客户端能够正确地处理服务器返回的实体主体。如果服务器未提供 Content-Type
,或者提供的值不正确,客户端可能会无法正确解释响应的内容,导致显示错误或无法处理数据。
6.6.9 Expires
Expires
是HTTP响应报文的首部字段之一,用于指定响应的实体主体的过期时间。它告诉客户端在过了这个过期时间后,客户端应该丢弃缓存的响应并向服务器发起新的请求。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Expires: Thu, 31 Dec 2023 12:00:00 GMT
在上述示例中,Expires: Thu, 31 Dec 2023 12:00:00 GMT
表示响应的实体主体将在2023年12月31日12:00:00(GMT时间)之后过期。在这之后,客户端应该向服务器发起新的请求以获取更新后的内容。
Expires
头部字段对于控制缓存的行为很重要,但它有一些缺点。首先,它依赖于服务器和客户端的时钟同步。如果它们的时钟不同步,可能导致缓存不按预期地工作。其次,由于缓存时间是预先设定的,如果资源在预定时间之前发生了更改,客户端仍然可能得到过期的内容。
在HTTP/1.1版本中,Cache-Control
(max-age)首部字段通常更为推荐,因为它提供更灵活和精确的缓存控制。如果 Cache-Control
和 Expires
同时存在,Cache-Control
的优先级更高。
6.6.10 Last-Modified
Last-Modified
是HTTP响应报文的首部字段之一,用于指示服务器最后修改资源的时间。这个字段通常用于支持条件请求,使客户端能够在必要时验证资源是否发生了变化。
示例:
HTTP/1.1 200 OK
Date: Wed, 29 Dec 2023 12:00:00 GMT
Content-Type: text/html
Last-Modified: Wed, 28 Dec 2023 08:30:00 GMT
在上述示例中**,Last-Modified: Wed, 28 Dec 2023 08:30:00 GMT
表示服务器最后修改资源的时间是2023年12月28日08:30:00(GMT时间)。**
当客户端首次请求资源时,服务器会返回资源的 Last-Modified
时间。然后,客户端可以在之后的请求中使用 If-Modified-Since
头部字段,将上次获取到的 Last-Modified
时间传递给服务器。服务器会检查这个时间,并判断资源是否在该时间之后被修改。如果没有修改,服务器可能会返回一个 304 Not Modified
的响应,告诉客户端可以使用缓存的版本。
使用 Last-Modified
和条件请求可以有效减少不必要的网络传输,因为只有在资源发生变化时才会重新传输资源。
需要注意的是,Last-Modified
并不是一个绝对精确的时间戳,而是服务器认为资源最后修改的时间。一些场景下,由于服务器的时间同步问题,或者因为文件系统的时间戳分辨率有限,可能导致这个时间戳并不完全准确。
6.7 为Cookie服务的首部字段
为Cookie服务的首部字段主要是在HTTP请求和响应中用于传递和管理Cookie信息的字段。主要涉及的首部字段包括:
-
Cookie
首部字段:-
作用: 在HTTP请求中,客户端通过
Cookie
首部字段将之前服务器设置的Cookie信息发送给服务器。 -
示例:
GET /path/resource HTTP/1.1 Host: www.example.com Cookie: user_id=12345; session_token=abcde
-
-
Set-Cookie
首部字段:-
作用: 在HTTP响应中,服务器通过
Set-Cookie
首部字段来设置新的Cookie或修改现有的Cookie,并将其传递给客户端。 -
示例:
HTTP/1.1 200 OK Content-Type: text/html Set-Cookie: user_id=12345; Expires=Wed, 29 Dec 2023 12:00:00 GMT; Path=/; Secure; HttpOnly Set-Cookie: session_token=abcde; Expires=Wed, 29 Dec 2023 12:00:00 GMT; Path=/; Secure; HttpOnly
Set-Cookie
首部字段的值包含了一系列Cookie属性,如**Expires
(指定过期时间)、Path
(指定Cookie的路径)、Secure
(要求Cookie只在HTTPS连接中传输)、HttpOnly
(限制JavaScript访问Cookie)等。** -
Cookie是一种用于在Web浏览器和服务器之间存储状态信息的机制。客户端通过发送包含 Cookie
首部字段的HTTP请求,将存储在本地的Cookie信息传递给服务器。服务器则通过发送包含 Set-Cookie
首部字段的HTTP响应,来设置新的Cookie或更新现有的Cookie。这样,通过这种状态管理机制,Web应用程序可以实现用户认证、会话管理等功能。
6.8 其他首部字段
HTTP首部字段是可以自行扩展的, 因此在Web服务器和浏览器的应用上会出现很多非标准的首部字段
6.8.1 X-Frame-Options
X-Frame-Options
是一个HTTP响应头部字段,用于控制网页是否允许在 <frame>
、<iframe>
、<embed>
或者 <object>
中显示。这个字段有助于防止点击劫持攻击(Clickjacking)。
示例:
HTTP/1.1 200 OK
Content-Type: text/html
X-Frame-Options: DENY
在上述示例中,X-Frame-Options: DENY
表示浏览器不允许页面在<frame>
、<iframe>
、<embed>
或者 <object>
中显示。这样,如果存在点击劫持攻击,攻击者无法将目标网页嵌套到一个透明的iframe中,从而迷惑用户进行一些不安全的操作。
常见的 X-Frame-Options
值包括:
- DENY: 完全禁止页面在任何情况下嵌套到框架中。
- SAMEORIGIN: 允许页面在相同域名下的框架中显示。
- ALLOW-FROM uri: 允许页面在指定的URI中显示。
示例:
X-Frame-Options: ALLOW-FROM https://example.com
在这个示例中,页面可以在 https://example.com
中的框架中显示。
通过使用 X-Frame-Options
头部字段,网站管理员可以增加对点击劫持攻击的防护,确保其网站在嵌套到iframe中时有明确的控制和限制。
6.8.2 X-XSS-Protection
X-XSS-Protection
是一个HTTP响应头部字段,用于启用或禁用浏览器内建的跨站脚本(XSS)过滤器。这个过滤器可以帮助防止恶意脚本的注入,提高网站的安全性。
示例:
HTTP/1.1 200 OK
Content-Type: text/html
X-XSS-Protection: 1; mode=block
在上述示例中,X-XSS-Protection: 1; mode=block
启用了浏览器的XSS过滤器,并且如果检测到XSS攻击,浏览器将停止渲染页面。
常见的 X-XSS-Protection
值包括:
- 0: 禁用浏览器的内建XSS过滤器。
- 1: 启用浏览器的内建XSS过滤器,如果检测到XSS攻击,浏览器将尝试自动修复,并停止渲染页面。
- 1; mode=block: 启用浏览器的内建XSS过滤器,如果检测到XSS攻击,浏览器将停止渲染页面,而不会尝试自动修复。
开启XSS过滤器有助于防范一类常见的安全漏洞,即跨站脚本攻击。XSS攻击通常涉及将恶意脚本插入到网页中,然后在用户浏览该网页时执行这些脚本。通过启用浏览器的XSS过滤器,可以增强对这类攻击的防护。
6.8.3 DNT
DNT
,或称为 “Do Not Track”,是一个HTTP请求头部字段,用于表示用户的隐私偏好。该字段是用户在浏览器设置中选择启用 “Do Not Track” 选项后发送的,**表明用户不希望被跟踪。**然而,DNT
并不强制执行,其实际效果依赖于网站和广告平台的遵守。
示例:
GET /path/resource HTTP/1.1
Host: www.example.com
DNT: 1
在上述示例中,DNT: 1
表示用户启用了 “Do Not Track” 选项。
网站和广告平台可以选择遵守用户的 DNT
请求,不追踪用户的浏览行为。然而,由于 DNT
不是法律要求,也没有明确的标准规范,不是所有网站都会遵守。
6.8.4 P3P
P3P
(Platform for Privacy Preferences Project)是一个已经被废弃的隐私标准,旨在**提供一种标准化的方法,使网站能够向用户传达其隐私政策。**通过使用 P3P
,网站可以通过一个简短的代码片段将其隐私政策信息传递给用户代理(例如浏览器),从而使用户能够了解和控制其个人信息的使用。
P3P
使用一种特定的语法来表示网站的隐私政策,包括如何收集、使用、披露和存储用户的个人信息。该信息以紧凑的、可被机器读取的方式传递给用户代理,用户代理可以根据这些信息来决定是否接受网站的隐私政策。
示例:
HTTP/1.1 200 OK
Content-Type: text/html
P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
在上述示例中,P3P
头部字段包含一个P3P策略字符串。该字符串由不同的令牌组成,每个令牌代表一个特定的隐私偏好或政策。
然而,P3P
在实际应用中并没有取得广泛成功,因为它存在一些缺点和问题。例如,它被认为过于复杂,缺乏实质性的法律依据,而且用户代理的支持也并不普遍。由于这些原因,P3P
已经被认为是过时和废弃的,并且现代的隐私政策传达更多依赖于其他方法,例如网站的隐私声明或使用其他隐私技术。
这篇关于第六章HTTP首部的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!