转载于海内博客:https://scriptrunz.com/zh-cn/…
HTTP 报文头
HTTP 报文头也叫报文首部。
HTTP 头部字段是形成 HTTP 报文的因素之一。在客户端与服务器之间以 HTTP 协定进行通信的过程中,无论是申请还是响应都会应用头部字段,它能起到传递额定重要信息的作用。
HTTP 首部字段是由首部字段名和字段值形成的,两头用 冒号:
分隔,上面是一个 HTTP 报文头的例子:
GET / HTTP/1.1
Host: hackr.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Ge
Accept: text/html,application/xhtml+xml,application/xml;q=0
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
If-Modified-Since: Fri, 31 Aug 2007 02:02:20 GMT
If-None-Match: "45bae1-16a-46d776ac"
Cache-Control: max-age=0
看不懂这些字段代表什么意思对吧?读完本文就全弄懂了。
通用首部字段
通用首部字段是指:申请报文和响应报文单方都会应用的字段。
Cache-Control
Cache-Control 通过设置不同的指令能够管制缓存的行为,指令格局为:
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: max-age=<seconds>
指令参数大略能够分为三类:
- 管制可缓存性。
- 管制到期工夫。
- 管制从新验证 & 从新加载。
管制缓存
- no-cache 会强制验证数据的有效期,以避免获取到过期资源。
- no-store 会禁止缓存服务器缓存数据。(个别意味着数据中含有机密信息
- only-if-cached:仅从缓存服务器获取数据,保障申请绝不会达到源服务器,如果缓存服务器没有该资源,则返回状态码 504(GateWay Timeout)。
- public:表明响应能够被任何对象(包含:发送申请的客户端,代理服务器,等等)缓存
- private:表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。
管制到期工夫
- max-age:设置缓存存储的最大周期,超过这个工夫缓存被认为过期 (单位秒)。客户端只接管
缓存工夫 <max-age
的数据。 - s-maxage:笼罩 max-age 或 Expires 字段,但它只实用于共享缓存(例如代理服务器),公有服务器会疏忽这个字段。
- max-stale:示意客户端违心接管一个过期的资源,只有
资源的过期工夫 <max-stale 的值
。 - min-fresh:示意客户想要的资源至多在指定的秒数内依然是陈腐的。
HTTP/1.1 版本的缓存服务器遇到同时存在 Expires 首部字段的状况时,会优先解决 max-age 指令,而疏忽掉 Expires 首部字段。而 HTTP/1.0 版本的缓存服务器的状况却相同,max-age 指令会被疏忽
从新验证和从新加载
- proxy-revalidate 指令要求所有的缓存服务器在接管到客户端带有该指令的申请返回响应之前,必须再次验证缓存的有效性,与 must-revalidate 的性能雷同。
- no-transform:禁止对资源进行转换。Content-Encoding,Content-Range,Content-Type 标头不得被代理批改。例如,一个不通明的代理可能会在图像格式之间进行转换,以节俭缓存空间或缩小慢速链接上的流量,而这个行为会被 no-transform 禁止。
示例
- 禁止缓存:
Cache-Control: no-store
-
缓存动态资源,例如图像,CSS 文件和 JavaScript 文件:
Cache-Control:public, max-age=31536000
- 须要从新验证
指定 no-cache 或 max-age=0, must-revalidate 示意客户端能够缓存资源,每次应用缓存资源前都必须从新验证其有效性。这意味着每次都会发动 HTTP 申请,但当缓存内容仍无效时能够跳过 HTTP 响应体的下载。
Cache-Control: no-cache 0
Cache-Control: max-age=0, must-revalidate
Connection
Connection 头(header)决定以后的事务实现后,是否会敞开网络连接。如果该值是keep-alive
,网络连接就是长久的,不会敞开,使得对同一个服务器的申请能够持续在该连贯上实现。
从 HTTP/1.1 版本开始,所有连贯默认为长久连贯。
Date
表明 HTTP 报文的创立日期和工夫。日期工夫格局有好几种,这里列出一种常见格局:Mon, 06 Feb 2023 01:19:14 GMT
Pragma
Pragma 是一个在 HTTP/1.0 中规定的通用首部,在 HTTP/1.1 协定被 Cache-Control 代替。当初它用来向后兼容只反对 HTTP/1.0 协定的缓存服务器。
Trailer
Trailer 在分块传输编码时会被用到,它用来在音讯块前面增加额定的元信息。
举个例子:上面的报文中 Trailer 指定了 Expires 字段,在音讯块前面呈现了 Expires 字段。
HTTP/1.1 200 OK
Date: Tue, 03 Jul 2012 04:40:56 GMT
Content-Type: text/html
...
Transfer-Encoding: chunked
Trailer: Expires
...(报文主体)...
Expires: Tue, 28 Sep 2004 23:59:59 GMT
Transfer-Encoding
规定传输报文时采纳的编码方式,可选的编码方式如下:
- chunked
数据以一系列分块的模式进行发送。在每一个分块的结尾须要增加以后分块的长度(十六进制),前面紧跟着 ‘\r\n’,之后是分块自身,前面也是 ’\r\n’。终止块是一个惯例的分块,不同之处在于其长度为 0。
HTTP/1.1 200 OK
Date: Tue, 03 Jul 2012 04:40:56 GMT
Cache-Control: public, max-age=604800
Content-Type: text/javascript; charset=utf-8
Expires: Tue, 10 Jul 2012 04:40:56 GMT
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Encoding: gzip
Transfer-Encoding: chunked
Connection: keep-alive
cf0\r\n ←16 进制(10 进制为 3312)
3312 字节数据 \r\n
392\r\n ←16 进制(10 进制为 914)
914 字节数据 \r\n
0\r\n
\r\n
- compress
采纳 Lempel-Ziv-Welch (LZW) 压缩算法。这种内容编码方式曾经被大部分浏览器弃用。
- deflate
采纳 zlib 构造,和 deflate 压缩算法。
- gzip
示意采纳 Lempel-Ziv coding (LZ77) 压缩算法,以及 32 位 CRC 校验的编码方式。这个编码方式最后由 UNIX 平台上的 gzip 程序采纳。处于兼容性的思考,HTTP/1.1 规范提议反对这种编码方式的服务器应该辨认作为别名的 x-gzip 指令。
- identity
用于表明本身未通过压缩和批改。
Transfer-Encoding 是一个逐跳传输音讯首部,即仅利用于两个节点之间的消息传递。如果想要将压缩后的数据利用于整个连贯,那么应该应用端到端传输音讯首部 Content-Encoding。
Upgrade
用于检测是否有可用的、更高版本的 HTTP 协定。
如果应用了 Upgrade 字段,Connection 字段的值会被指定为 Upgrade,比方:
Upgrade:TLS/1.0
Connection:Upgrade
Via
Via 用于追踪客户端和服务器之间报文的传输门路,也可用于避免循环申请。格局:
Via: [<protocol-name> "/"] <protocol-version> <host> [":" <port>]
or
Via: [<protocol-name> "/"] <protocol-version> <pseudonym>
- <protocol-name>:所应用的协定名称,如 “HTTP”。
- <protocol-version>:所应用的协定版本号,例如 “1.1”。
- <host> and <port>:公共代理的 URL 及端口号。
- <pseudonym>:外部代理的名称或别名。
Warning
正告报文呈现了问题,格局:Warning: <warn-code> <warn-agent> <warn-text> [<warn-date>]
申请报文字段
Accept
用来告知服务器能够解决的内容类型,例如:
Accept: <MIME_type>/<MIME_subtype>
Accept: <MIME_type>/*
Accept: */*
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
- <MIME_type>/<MIME_subtype>,比方 text/html。
*
代表任意类型,比方 image/* 能够用来指代 image/png、image/svg、image/gif 以及任何其余的图片类型。- q 代表权重。
Accept-Charset
用于申明客户端能够解决的字符集类型,例如:
Accept-Charset: <charset>
Accept-Charset: utf-8, iso-8859-1;q=0.5, *;q=0.1
Accept-Encoding
用于申明客户端可能解决的编码方式,例如:
Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5
- gzip 示意采纳 Lempel-Ziv coding (LZ77) 压缩算法,以及 32 位 CRC 校验的编码方式。
- compress 示意采纳 Lempel-Ziv-Welch (LZW) 压缩算法。
- deflate 示意采纳 zlib 构造和 deflate 压缩算法。
- br 示意采纳 Brotli 算法的编码方式。
- identity 示意本身未通过压缩和批改。
Accept-Language
用于申明客户端能够了解的语言,比方:
Accept-Language: <language>
Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5
Authorization
用于提供给服务器验证身份的凭据,容许其拜访受爱护的资源,比方:
Authorization: <auth-scheme> <authorization-parameters>
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Basic 身份验证:首先将用户名和明码应用一个冒号拼接(username:password),而后将生成的字符串进行 base64 编码。
除了 Basic 编码方式,还有 Digest、Negotiate 等形式。
Expect
客户端发送带有 Expect 音讯头的申请,等服务器回复后再发送音讯体,例如:
Expect: 100-continue
服务器查看申请音讯头,可能会返回一个状态码为 100 (Continue) 的回复来告知客户端持续发送音讯体,也可能会返回一个状态码为 417 (Expectation Failed) 的回复来告知对方要求不能失去满足。
From
附带一个电子邮箱地址,例如:
From: webmaster@example.org
Host
指明本次申请的指标服务器主机名和端口号。
- 如果没有蕴含端口号,会主动应用被申请服务的默认端口
- 所有 HTTP/1.1 申请报文中必须蕴含一个 Host 字段。对于短少 Host 头或者含有多个 Host 头的 HTTP/1.1 申请,可能会收到 400(Bad Request)状态码。
If-Match
形如 If-xxx 这种款式的申请首部字段,都可称为条件申请。服务器接管到附带条件的申请后,只有判断指定条件为真时,才会执行申请。例如:
If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者统一时,才会执行申请。反之,则返回状态码 412 Precondition Failed 的响应。
If-Modified-Since
If-Modified-Since 用于确认客户端领有的本地资源的有效性,例如:
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
服务器在收到带有 If-Modified-Since 字段的申请后,会将该字段值和资源更新工夫做比拟,若资源没有更新,则返回 304 状态码(Not Modified)。
If-None-Match
与 If-Match 的作用相同。
If-Range
If-Range HTTP 申请头字段用来使得 Range 头字段在肯定条件下起作用:当字段值中的条件失去满足时,Range 头字段才会起作用,例如:
If-Range: Wed, 21 Oct 2015 07:28:00 GMT
字段值中既能够用 Last-Modified 工夫值用作验证,也能够用 ETag 标记作为验证,但不能将两者同时应用。
If-Unmodified-Since
与 If-Modified-Since 作用相同。
Max-Forwards
用于限度 TRACE 办法可通过的服务器(通常指代理服务器)数目。
发送蕴含首部字段 Max- Forwards 的申请时,该字段以十进制整数模式指定可通过的服务器最大数目。每通过一个服务器,Max-Forwards 的值减 1。当服务器接管到 Max-Forwards 值为 0 的申请时,则不再进行转发,而是间接返回响应。
Proxy-Authorization
用于客户端和代理服务器之间的认证,例如:
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
Range
Range 字段用于分批申请资源,上面的示例示意申请获取从第 5001 字节至第 10000 字节的资源。
Range: bytes=5001-10000
接管到附带 Range 首部字段申请的服务器,会在解决申请之后返回状态码为 206 Partial Content 的响应。无奈解决该范畴申请时,则会返回状态码 200 OK 的响应及全副资源。
Referer
Referer 申请头蕴含了以后申请页面的起源页面的地址,即示意以后页面是通过此起源页面里的链接进入的。服务端个别应用 Referer 申请头辨认拜访起源,可能会以此进行统计分析、日志记录以及缓存优化等。
Referer 申请头可能裸露用户的浏览历史,波及到用户的隐衷问题,所以个别用于 HTTPS 协定。
TE
表明客户端可能解决的传输编码方式及绝对优先级,例如:
TE: gzip, deflate;q=0.5
User-Agent
User-Agent 首部蕴含了一个特色字符串,用来让网络协议的对端来辨认发动申请的用户代理软件的利用类型、操作系统、软件开发商以及版本号。比方 Google 的 UA 字符串:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
响应报文字段
Accept-Ranges
表明服务器是否反对范畴申请,能够解决范畴申请时指定字段值为 bytes,反之则为 none,指令格局:
Accept-Ranges: bytes
Age
表明资源在代理服务器缓存了多久,以秒为单位,指令格局:
Age: 24
ETag
ETag 是资源的惟一标识符,应用 ETag 能疾速确定资源是否产生过变动。(能够了解为资源的“指纹”)
ETag 有强弱之分,资源即便产生了一丁点的变动也会扭转 强 ETag 值
,对应的,只有资源产生较大变动才会扭转 弱 ETag 值
,此时会在字段开始处附加W/
:
ETag: W/"0815"
Location
用于将页面重定向至新的地址,个别与 3xx 状态码配合应用,例如:
Location: <url>
Proxy-Authenticate
Proxy-Authenticate 会把由代理服务器所要求的认证信息发送给客户端,例如:
Proxy-Authenticate: Basic realm="Access to the internal site"
Retry-After
用于告知客户端应该在多久之后再次发送申请。次要配合状态码 503 Service Unavailable,或 3xx Redirect 响应一起应用,例如:
Retry-After: 120(以秒为单位)
Server
表明服务器的软件和版本信息,指令格局:
Server: Apache/2.2.6 (Unix) PHP/5.2.5
Vary
决定缓存是否应用,对于缓存,倡议用 cache-control 而非 vary。
WWW-Authenticate
WWW-Authenticate 定义了应该应用何种验证形式去获取对资源的连贯,例如服务器利用该字段规定了 Basic 认证:
WWW-Authenticate: Basic realm="Access to the staging site"
WWW-Authenticate header 通常会和一个 401 Unauthorized 的响应一起被发送。
报文实体字段
Allow
用于枚举资源所反对的 HTTP 办法的汇合,指令格局:
Allow: GET, HEAD
如果 Allow 字段的值为空,阐明资源不承受应用任何 HTTP 办法的申请,这可能是因为服务器须要长期禁止对资源的任何拜访。
Cotent-Encoding
音讯文本的编码类型,指令格局:
Content-Encoding: deflate, gzip
指令参数:
- gzip 示意采纳 Lempel-Ziv coding (LZ77) 压缩算法,以及 32 位 CRC 校验的编码方式。
- compress 示意采纳 Lempel-Ziv-Welch (LZW) 压缩算法。
- deflate 示意采纳 zlib 构造和 deflate 压缩算法。
- br 示意采纳 Brotli 算法的编码方式。
Cotent-Language
Content-Language 用来阐明服务器心愿访问者采纳的语言或语言组合,例如报文的 Content-Language 字段值为de
,那么阐明这份文件是为说德语的人提供的,然而这并不意味着文本是德文,它也可能是英文等其余语言:
Content-Language: de
Content-Length
用于指明发送给客户端的 音讯主体
的大小,用十进制数字示意,例如:
Content-Length: 15900
Content-Location
对应资源的 URL。
Content-Range
用来示意一个数据片段在整个文件中的地位,例如:
Content-Range: bytes 200-1000/67589
Content-Type
用于告知客户端响应报文内容的内容类型,例如:
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=something
指令参数:
- media-type
资源的 MIME 类型,比方 text/html、multipart/form-data。
- charset
字符编码标准。
Expires
用于告知客户端缓存的生效日期,指令格局:
Expires: Wed, 21 Oct 2015 07:28:00 GMT
如果在 Cache-Control 响应头设置了 max-age 或者 s-max-age 指令,那么 Expires 头会被疏忽。
Last-Modified
资源最初一次批改的工夫,指令格局:
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
Cookie 相干字段
Set-Cookie
服务器利用 Set-Cookie 字段来告知客户端 cookie,例如设置一个永恒 cookie:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
- expires:表明 Cookie 的有效期。当省略 expires 属性时,其有效期仅限于以后浏览器会话(Session) 时间段内。浏览器一旦敞开则 cookie 生效。
- path:指定一个 URL 门路,这个门路必须呈现在要申请的资源的门路中才能够发送 Cookie 标头。
- domain:指定 cookie 能够送达的主机名。
- secure:表明 cookie 只能在 HTTPS 应用,HTTP 不能够。
- HttpOnly:禁止 JS 脚本取得 Cookie。其次要目标为避免跨站脚本攻打 (Cross-site scripting,XSS) 对 Cookie 的信息窃取。
示例
-
会话期 cookie
Set-Cookie: sessionId=38afes7a8
会话期 cookie 将会在客户端敞开时被移除。会话期 cookie 不设置 Expires 或 Max-Age 属性。
-
长久化 cookie
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT Set-Cookie: id=a3fWa; Max-Age=2592000
长久化 cookie 不会在客户端敞开时生效,而是在特定的日期(Expires)或者通过一段特定的工夫之后(Max-Age)才会生效。
Cookie
客户端在向服务器发 HTTP 申请时附带 Cookie 以取得服务器的认证。(Cookie 值来源于上文的 Set-Cookie 字段值)
报文头部字段的转发策略
一个 HTTP 申请要跨过多个代理服务器,通过屡次代理服务器的转发能力达到指标服务器。
代理服务器做转发时,对原 HTTP 报文头部字段有两种解决形式:
- 逐跳策略:单次转发无效。
- 端到端策略:始终无效,确保字段被发送到指标服务器。
哪些字段是逐条策略?哪些又是端到端策略?
除了上面这些字段为逐跳策略外,其余字段都属于端到端策略:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
辨别容易混同的字段
TE、Accept-Encoding、Transfer-Encoding、Content-Encoding
- Transfer-Encoding:用于指定传输报文主体时应用的编码方式,属于逐跳首部,即只在两个节点间无效。
- TE:用于告知服务器客户端可能解决的编码方式和绝对优先级,属于逐跳首部,即只在两个节点间无效。
- Content-Encoding:用于指定报文主体曾经采纳的编码方式,属于端到端首部,即在整个传输过程中无效。
- Accept-Encoding:用于告知服务器客户端可能解决的编码方式和绝对优先级,属于端到端首部,即在整个传输过程中无效。
Loaction 与 Content-Location
Location 指定的是一个重定向申请的目标地址(或者新创建的文件的 URL)。
Content-Location 指向的是可供拜访的资源的间接地址。
Proxy-Authenticate、WWW-Authenticate
Proxy-Authenticate 规定了客户端与代理服务器的认证形式,而 WWW-Authenticate 规定了客户端与服务器的认证形式。
有关联的字段
ETag、If-Match、If-None-Match
Etag 由服务器端生成,客户端通过 If-Match 或者说 If-None-Match 这个条件判断申请来验证资源是否批改。常见的是应用 If-None-Match,比方申请一个文件的流程可能如下:
第一次申请:
- 客户端发动 HTTP GET 申请一个文件;
- 服务器解决申请,返回文件内容和一堆 Header,当然包含 Etag(例如 ”2e681a-6-5d044840″)。
第二次申请:
- 客户端发动 HTTP GET 申请一个文件,留神这个时候客户端同时发送一个 If-None-Match 头,这个头的内容就是第一次申请时服务器返回的 Etag:2e681a-6-5d044840。
- 服务器判断发送过去的 Etag 和计算出来的 Etag 匹配,因而 If-None-Match 为 False,不返回 200,返回 304,客户端持续应用本地缓存;
Cache-Control、max-age、Expires
当首部字段 Cache-Control 有指定 max-age 指令时,会优先解决 max-age 指令,而疏忽 Expires 字段。
参考:
- 《图解 HTTP》
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers
- https://cloud.tencent.com/developer/chapter/13542
- https://blog.csdn.net/swt369/article/details/77847896