首部内容为客户端和服务器分别处理请求和响应提供所需要的信息,给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
一个简单的场景,就是客户端和服务端的请求协商,借助下面插图理解。
HTTP首部字段结构
字段名:字段值
HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分隔,最后用CRLF换行标识字段结束。
同一字段可以多个值
字段值对应单个 HTTP 首部字段可以有多个值,用“,”分隔开。
Keep-Alive: timeout=15, max=100
字段名不区分大小写
字段名中不允许出现空格和下划线“_”,允许出现中划线“-”
字段名后必须紧跟“:”
字段原则上不能重复
若 HTTP 首部字段重复了会如何?
当 HTTP 报文首部中出现了两个或两个以上具有相同首部字段名时 会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑 的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的 首部字段,而有些则会优先处理最后出现的首部字段。
4种HTTP首部字段(按用途)
- 通用首部字段(General Header Fields): 请求报文和响应报文两方都会使用的首部。
- 请求首部字段(Request Header Fields):从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
- 响应首部字段(Response Header Fields):从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
通用Header(HTTP/1.1 )
Cache-Control
操作缓存的工作机制,控制缓存的行为
样例:
Cache-Control: private, max-age=0, no-cache
public: 可向任意方提供响应缓存,浏览器和代理服务缓存都有效
private: 仅向指定用户返回响应,只有浏览器缓存有效
no-cache: 防止从缓存中返回过期的资源
可以在客户端存储资源,每次都必须去服务端做新鲜度校验,来决定从服务端获取新的资源(200)还是使用客户端缓存(304)。也就是所谓的协商缓存。
服务器返回的响应中,若报文首部字段 Cache-Control 中对 no-cache 字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数. Cache-Control: no-cache=Location
no-cache 代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,也许称为 do-not-serve-from-cache-without-revalidation 更合适。有效性校验. 相当于「 Cache-Control: max-age=0, must-revalidate 」
no-store: 该指令规定缓存不能在本地存储请求或响应的任一部分。
s-max-age: 只适用于供多位用户使用的公共缓存服务器,单位秒,用于标识CDN的有效时间。
优先级更高,可以直接忽略Expires(绝对过期时间)以及max-age(相对过期时间)
max-age: 缓存相对过期时间,如果判定缓存资源的缓 存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。 另外,当指定 max-age 值为 0,那么缓存服务器通常需要将请求转发 给源服务器。max-age 数值代表资源保存为缓存的最长时间. 对应的返回报文(通用头)中的
Date字段。
优先级: s-max-age > max-age > expires
min-fresh: 返回至少还未过指定时间的缓存资源,最小新鲜时间(距离过期时间大于等于min-fresh值)
max-stale: 指示缓存资源,即使超过过期时间多久,也照常接收。
only-if-cached: 该指令要求缓存服务器不重新 加载响应,也不会再次确认资源有效性,直接从缓存中取资源。
must-revalidate: 代理会向源服务器再次验证即将返回的响 应缓存目前是否仍然有效。使用 must-revalidate 指令会忽略请求的 max-stale 指令(即使已 经在首部使用了 max-stale,也不会再有效果)
no-transform: 无论是在请求还是响应中,缓存都不能改 变实体主体的媒体类型
Connection
管理持久连接
HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持 久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。
断开长连接
Connection: Close
建立长链接
Connection: Keep-Alive
建立长连接的过程:
Date
创建 HTTP 报文的日期和时间。
Transfer-Encoding
规定了传输报文主体时采用的编码方式。
请求Header
Accept
可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒体类型。通信模型如下:
多类型优先级: 若想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值,用分号(;)进行分隔。权重值 q 的范围是 0~1(可精确到小数点 后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为q=1.0。q = 0表示拒绝。
上述图片中,Accept标识浏览器最希望使用的是html文件,权重是1,其次是text/plain,权重是0.3
HTTP内容协商中的
“,”要比“;”的语气更强,这与大多数的语法都是相反的。
Accept-Charset
可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字 段 Accept 相同的是可用权重 q 值来表示相对优先级。
样例:
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
Accept-Encoding
用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
Accept-Encoding: gzip, deflate
Accept-Language
用来告知服务器用户代理能够处理的自然 语言集(指中文或英文等),以及自然语言集的相对优先级。可一次 指定多种自然语言集。
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
Authorization
用来告知服务器,用户代理的认证信息(证 书值)。通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中
Host
告知服务器,请求的资源所处的互联网主机名和端 口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段
If-Match & If-None-Match [条件请求]
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求.
结合返回头中ETag使用,作为缓存策略。ETag存在性能问题,只能作为Last-Modified的补充项。
只有当 If-Match 的字段值跟 ETag 值匹配一致时,服务器才会 接受请求
状态码412: 服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者一致时,才会执行请求。反之,则返回状态码 412 Precondition Failed 的响 应。
还可以使用星号(*)指定 If-Match 的字段值。针对这种情况,服务器将会忽略 ETag 的值,只要资源存在就处理请求。
If-Modified-Since & If-Unmodified-Since[条件请求]
如果在 If-Modified-Since 字段指定的日期时间后,资源发生了更新,服务器会接受请求, 其值是上次请求response中的Last-Modified时间或者本地文件最后修改日期,对比该时间和服务器上的最后的修改时间是否一致。
状态码304: 在指定 If-Modified-Since 字段值的日期时间之后,如果请求的资源 都没有过更新,则返回状态码 304 Not Modified 的响应。
Range
只需获取部分资源的范围请求,包含首部字段 Range 即可告知服 务器资源的指定范围。
接收到附带 Range 首部字段请求的服务器,会在处理请求之后返回状 态码为 206 Partial Content 的响应。无法处理该范围请求时,则会返 回状态码 200 OK 的响应及全部资源。
Referer
告知服务器请求的原始资源的 URI,也就是清楚从哪个web页面发起的请求。
Cookie
服务器收到的Cookie信息
响应Header
Accept-Ranges
用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。
当不能处理范围请求时,Accept-Ranges:none
Age
告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。
ETag
告知客户端实体标识。它是一种可将资源以字符串 形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。
强ETag:
ETag: "82e22293907ce725faf67773957acd12"
弱ETag:
ETag: W/"82e22293907ce725faf67773957acd12"
资源被缓存时,就会被分配唯一性标识。资源更新后,ETag值会随之改变。
强ETag值 和 弱ETag
强 ETag 值,不论实体发生多么细微的变化都会改变其值。 弱 ETag 值,只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
ETag存在性能问题,只能作为Last-Modified的补充项。
Location
将响应接收方引导至某个与请求 URI 位置不同的资源。基本上,该字段会配合 3xx :Redirection的响应,提供重定向的 URI。
Retry-After
告知客户端应该在多久之后再次发送请求。主要 配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使用。
浏览器收到301、302报文,会检查请求头里有没有“Location”。如果有,就从字段值里提取URI,发出新的HTTP请求。
Set-Cookie
开始状态管理所使用的cookie信息
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
NAME=VALUE
赋予Cookie的名称和值
domain=DOMAIN
作为Cookie适用对象的域名,默认为创建Cookie的域名
path=PATH
指定使用cookie的URI,默认为根
expires=DATE
Cookie的有效期,若不指明则默认为浏览器关闭前为止。
max-age=123
Cookie相对过期时间,单位是s,浏览器用收到报文的时间再加上max-age就是绝对的实效时间。优先级高于expires
Secure
仅在HTTPS安全通信时才会发送cookie
HttpOnly
Cookie不能被js修改
SameSite
防范跨站请求伪造。
Strict: 严格限定Cookie不能随着跳转链接跨站发送;
Lax: 允许Get、Head等安全方法,但紧致POST跨站发送;
None: 没有限制;
X-Frame-Options
用于控制网站内容 在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。
DENY
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM
uri表示该页面可以在指定来源的 frame 中展示。
X-XSS-Protection
针对跨站脚本 攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。
0: 将 XSS 过滤设置成无效状态
1: 将 XSS 过滤设置成有效状态
实体Header
Allow
用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。
Allow: GET, HEAD
Content-Encoding
告知客户端服务器对实体的主体部分选 用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。
Content-Encoding: gzip
Content-Language
告知客户端,实体主体使用的自然语言 (指中文或英文等语言)
Content-Length
实体主体部分的大小(单位是字节)。
注意: 对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。
Content-Length: 15000
Content-Range
针对范围请求(Range),返回响应时使用的首部字段 Content-Range,能告知客 户端作为响应返回的实体的哪个部分符合范围请求。
Content-Type
说明了实体主体内对象的媒体类型。和首部字 段 Accept 一样,字段值用 type/subtype 形式赋值。
Expires 绝对过期时间
将资源失效的日期告知客户端。 缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。
Expires: Wed, 04 Jul 2012 08:26:05 GMT
Last-Modified
指明资源最终修改的时间。
拓展,整体看下http缓存:
强制缓存命中失败才会命中协商缓存。
协商缓存中,ETag存在性能问题,只能作为Last-Modified的补充项。
缓存优先级: no-store(资源是否可复用) -> no-cache(缓存新鲜度校验) -> private&public确认 -> if-modified-since -> if-none-match
效果: 减少请求次数,提升加载速度。