图解 HTTP 笔记(六)——HTTP 首部

1,432 阅读25分钟

本章主要讲解了 HTTP 首部的结构,已经首部中各字段的用法。

一、HTTP 报文首部

httpstructure

上图是 HTTP 请求报文的结构。

HTTP 请求报文由方法、URI、HTTP 版本、HTTP 首部字段等组成。

请求报文首部信息实例:

GET / HTTP/1.1
Host: hackr.jp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/2010010
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*; q=0
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
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

HTTP 响应报文由 HTTP 版本、状态码(数字和原因短语)、HTTP 首部字段三部分组成。

下图是 HTTP 响应报文结构:

httpresstructure

响应报文的首部实例:

HTTP/1.1 304 Not Modified
Date: Thu, 07 Jun 2012 07:21:36 GMT
Server: Apache
Connection: close
Etag: "45bae1-16a-46d776ac"

二、HTTP 首部字段

2.1 HTTP 首部字段结构

HTTP 首部字段传递重要信息,其结构基本如下:

首部字段名:字段值

例如:

Content-Type:text/html

另外,有些首部字段可以有多个值,如下所示:

Keep-Alive:timeout=15,max=100

2.2 HTTP 首部字段类型

HTTP 首部字段根据实际用途被分为四种类型。

  • 通用首部字段:请求报文和响应报文都会使用到的首部字段。
  • 请求首部字段:从客户端向服务端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级的信息。
  • 响应首部字段:从服务端向客户端发送响应报文时的首部。补充了响应的附加内容,也会要求客户端附加的内容信息。
  • 实体首部字段:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体内容相关的信息。

2.3 HTTP 首部字段一览

2.3.1 通用首部字段
首部字段名 说明
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末尾的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知
2.3.2 请求首部字段
首部字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorization Web 信息认证
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在的服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与 If-Match 相反)
If-Range 资源未更新时发送实体 Byte 的范围请求
If-Unmodified-Since 比较资源的更新时间(与 If-Modified-Since 相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中 URI 的原始获取方
TE 传输编码的优先级
User-Agent HTTP 客户端程序的信息
2.3.3 响应首部字段
首部字段名 说明
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定 URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP 服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息
2.3.4 实体首部字段
首部字段名 说明
Allow 资源可支持的 HTTP 方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(字节)
Content-Location 替代对应资源的 URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改时间

以上就是最常用的一些 HTTP 首部字段。

其他还有一些非 HTTP/1.1 规范的首部字段也用的比较多,比如 Set-Cookie、Cookie 等等。

此外,HTTP 首部根据将定义成缓存代理和非缓存代理的行为,分成了两种类型——端到端首部(End-to-End Header)和逐跳首部(Hop-by-Hop Header)。

端到端首部类的首部字段会转发给请求/响应的最终接受对象,且必须保存在由缓存生成的响应中,另外规定它必须转发;

逐跳首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1 之后的版本中使用逐跳首部需要提供 Connection 首部字段。

下面这些字段都属于逐跳首部字段:

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • Trailer
  • TE
  • Transfer-Encoding
  • Upgrade

所有其余字段皆为端到端首部字段。

下面开始详细介绍各个首部字段。

2.4 HTTP/1.1 通用首部字段

2.4.1 Cache-Control

通过指定首部字段 Cache-Control,就能操作缓存的工作机制。

Cache-Control 的指令参数是可选的,多个指令之间通过逗号分开。该首部字段在请求和响应时都可以使用。

Cache-Control: private, max-age=0, no-cache

Cache-Control 可用指令如下:

请求指令:

指令 参数 说明
no-cache 强制向源服务器再次验证
no-store 不缓存请求或响应的任何内容
max-age=[秒] 必需 响应的最大 age 值
max-stale(=[秒]) 可省略 接受已过期的响应
min-fresh=[秒] 必需 期望在指定的时间内的响应仍然有效
no-transform 代理不可更改媒体类型
only-if-cached 从缓存获得资源
cache-extension - 新指令标记(token)

响应指令:

指令 参数 说明
public 可向任意方提供响应的缓存
private 可省略 仅向特定用户返回响应
no-cache 可省略 缓存前必须确认其有效性
no-store 不缓存请求或响应的任何内容
no-transform 代理不可更改媒体类型
must-revalidate 可缓存但必须再向源服务器进行确认
proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
max-age=[秒] 必需 响应的最大 age 值
s-maxage=[秒] 必需 公共缓存服务器响应的最大 age 值
cache-extension - 新指令标记(token)

规定是否缓存的指令:

public 指令

Cache-Control: public

当指定使用 public 指令时,则明确表明其他用户也可利用缓存。

private 指令

Cache-Control: private

当指定 private 指令后响应只以特定的用户作为对象,当该对象向服务器发起请求时,服务器会返回缓存的资源。

no-cache 指令

Cache-Control: no-cache

该指令的目的是为了防止使用过期的缓存资源。

如果客户端发送的请求中包含 no-cache 指令,则表示客户端将不会接受过期的缓存过的响应。于是,中间的代理服务器必须把请求转发给源服务器。

如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存,源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对资源响应进行缓存操作。


控制可执行缓存对象的指令:

no-store 指令

Cache-Control: no-store

当使用 no-store 指令时,暗示请求或响应中包含机密信息。

因此该指令规定缓存不能在本地存储请求或响应的任一部分。

注意

从字面意义来说,很容易把 no-cache 理解为不缓存,但事实上 no-cache 代表的是不缓存过期的资源,缓存会向源服务器确认有效性后再处理资源。no-store 才是真正的不进行缓存。


指定缓存期限和认证的指令:

s-maxage 指令

Cache-Control: smax-age=604800(单位:秒)

该指令功能和 max-age 相同,不同点是 s-maxage 指令只适合于供多位用户使用的公共缓存服务器。

当使用 smax-age 指令之后,直接会忽略 Expires 字段及 max-age 指令的处理。

max-age 指令

Cache-Control: max-age=604800(单位:秒)

当客户端发送的请求中包含 max-age 指令时,如果判定缓存资源的缓存时间数值比指定的数值更小,那么客户端就接收缓存的资源。另外,当指定 max-age 值为 0,那么缓存服务器通常需要将请求转发给源服务器(相当于是 no-cache)。

当服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再做确认,而 max-age 数值代表的是资源保存为缓存的最长时间。

应用 HTTP/1.1 版本的缓存的服务器遇到同时存在 Expires 首部字段的情况时,会优先处理 max-age 指令,而忽略掉 Expires 首部字段。而应用 HTTP/1.0 版本的服务器则恰恰相反

min-fresh 指令

Cache-Control: min-fresh=60(单位:秒)

min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源(即指定时间过后仍然是未过期的资源)。

max-stale 指令

Cache-Control: max-stale=3600(单位:秒)

使用 max-stale 表示接受过期的缓存资源,后面的值表示具体过期的时长,表示响应不能已经过时超过该给定的时间。如果不传递数值,则表示无论经过多久,客户端都能够接受。

only-if-cached 指令

Cache-Control: only-if-cached

使用该指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。即只接受已缓存的资源,并且不用向源服务器检查资源的有效性。若代理服务器本地缓存无响应,则返回 504 Gateway Timeout。

must-revalidate 指令

Cache-Control: must-revalidate

使用该指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。

使用 must-revalidate 指令会忽略 max-stale 指令。

proxy-revalidate 指令

Cache-Control: proxy-revalidate

该指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再验证资源的有效性。

no-transform 指令

Cache-Control: no-transform

该指令规定无论在请求还是响应中缓存都不能改变实体的媒体类型。

这样可以防止缓存或者代理压缩图片等类似操作。

2.4.2 Connection

这个首部字段有一下两个作用:

  • 控制不再转发给代理的首部自担
  • 管理持久连接
Connection: 不再转发的首部字段名

这条语句就表示指定的首部字段不再转发到下一级服务器(可能是代理)。

httpconn

除了上面的功能以外,该首部还可以管理持久连接:

Connection: close

该指令明确指定断开当前连接。(HTTP/1.1 的所有连接默认都是长连接)

Connection: keep-alive

以上指令明确指定当前连接为长连接。(适用于 HTTP/1.1 版本之前)

2.4.3 Date

该字段表明 HTTP 报文创建的日期和时间。

Date: Tue, 03 Jul 2012 04:40:59 GMT
2.4.4 Pragma

该字段是 HTTP/1.1 版本的遗留字段,为了向后兼容而定义。

Pragma: no-cache

Cache-Control: no-cache

功能一致。

2.4.5 Trailer

该字段事先说明在报文主体后记录了哪些首部字段,可用于 HTTP/1.1 版本分块传输编码时。

2.4.6 Transfer-Encoding

该首部字段指定了在传输报文主体时所使用的编码方式。

Transfer-Encoding: chunked
2.4.7 Upgrade

该首部字段用于检测 HTTP 协议及其他协议是否可以升级为更高版本进行通信,其参数值可以用来指定一个完全不同的通信协议。

2.4.8 Via

该首部字段是为了追踪客户端与服务器之间的请求和响应报文的传输路径。

报文经过代理或者网关时,会在首部字段 Via 中附加该服务器的信息,然后再进行转发。而且这个字段不仅可以用于追踪报文的转发,还可以避免请求回环发生。

httpvia

各个代理服务器会向 Via 添加自身服务器的信息。

其中 1.0 以及 1.1 的开头表示服务器的 HTTP 协议版本。

2.4.9 Warning

该首部自担通常告诉用户一些缓存相关的问题的警告,具体格式如下:

Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])

具体警告码可以查阅《图解 HTTP》表 6-7。

2.5 请求首部字段

请求首部字段是从客户端发往服务器端时请求报文中所使用的字段。

2.5.1 Accept
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

该首部字段可以通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可以使用 type/subtype 的形式一次指定多种媒体类型。

常用媒体类型:

  • 文本文件:

    text/html,text/plain,text/css,application/xhtml+xml,application/xml...
    
  • 图片文件

    image/jpg,image/gif,image/png...
    
  • 视频文件

    video/mpeg,video/quicktime...
    
  • 应用程序使用的二进制文件

    application/octet-stream,application/zip...
    
    

多个协议之间使用逗号分隔,分号之前代表媒体类型,分号之后代表权重。

当服务器提供多种内容时,会首先返回权重最高的媒体类型。

2.5.2 Accept-Charset
Accept-Charset: iso-8859-5,unicode-1-1;q=0.8

该字段可用来通知服务器用户代理支持的字符集以及字符集的权重。

2.5.3 Accept-Encoding
Accept-Encoding: gzip,deflate

该字段用来告知服务器用户代理支持的内容编码及内容编码格式的优先级。

以下是最常用的几个内容编码格式:

  • gzip

    由文件压缩程序 gzip(GNU zip)生成的编码格式(RFC1952)。

  • compress

    由 UNIX 文件压缩程序 compress 生成的编码格式。

  • deflate

    组合使用 zlib 格式及有 deflate 压缩算法生成的编码格式。

  • identity

    不执行压缩或者不会变化的默认编码格式。

2.5.4 Accept-Language

告知服务器能够处理的自然语言。

Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3

2.5.5 Authorization

该字段用于告知服务器用户代理的认证信息。

Authorization: Basic dWVub3NlbjpwYXNzd29yZA==

2.5.6 Expect
Expect: 100-continue

客户端使用该字段来告知服务器期望出现的某种特定行为。

如果服务器无法理解这种特定的行为,则会返回 417 Expectation Failed的错误。

2.5.7 From
From: info@hackr.jp

该字段用来告知服务器使用用户代理的用户电子邮箱地址。

2.5.8 Host
Host: www.hackr.jp

很多时候一台服务器上部署了多个网站,对应着多个域名,当 DNS 解析到服务器之后,我们需要知道用户访问的是哪个网址,以便分配到对应的端口给对应的程序进行处理,所以 Host 就用来告知服务器端用户访问的主机名称和端口号。

Host 首部是唯一一个必须被包含在请求内的首部字段。

如果服务器未设定主机名,那么发送一个空值即可。

2.5.9 If-Match

形如 If-xxx 的请求首部字段,都可以称为条件请求。服务器接收到条件请求之后,只有在判断条件为真时才会执行请求。

If-Match: "123456"

该首部字段属于附带条件之一,它会告知服务器匹配资源所用的实体标记(ETag,后面会讲)值。服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者一致时才会执行请求。反之会返回状态码 412 Precondition Failed 的响应。

使用 * 时,服务器会匹配任意的 ETag 值。

2.5.10 If-Modified-Since

该首部字段指定一个时间点,如果在该时间点之后有修改过资源,则会响应请求。

If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT

如果在这个时间点之后没有修改过资源,则返回 304 Not Modified 状态码的响应。

2.5.11 If-None-Match

该字段与 If-Match 的作用相反。当该字段的值不匹配资源的 ETag 时才会响应请求。

2.5.12 If-Range

该字段的值若是跟 ETag 的值或更新的日期时间相匹配,那么就作为范围请求处理;如果无法匹配的话就返回全体资源。

2.5.13 If-Unmodified-Since
If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT

该首部字段和 If-Modified-Since 作用相反,它的作用是告知服务器指定的资源只有在指定日期之后没有发生变更的情况下才处理请求,否则就返回 412 Precondition Failed 状态码。

2.5.14 Max-Forward

通过 TRACE 方法或者 OPTIONS 方法发送包含首部字段 Max-Forward 的请求时,该字段以十进制整数形式指定可经过的服务器的最大数目。

Max-Forward: 10

2.5.15 Proxy-Authorization
Proxy-Authorization: Basic dGlwObjkNLAGFfY5

该字段告知服务器认证所需要的信息,该认证行为发生在客户端与代理服务器之间。

2.5.16 Range
Range: bytes=5001-10000

该字段适用于只获取部分资源的范围请求,它告知了服务器所需要的服务器资源的指定范围。

接收到携带该字段请求的服务器会返回状态码为 206 Partial Content 的响应,如果无法处理该范围请求,则服务器会返回状态码为 200 OK 的响应以及全部资源。

2.5.17 Referer
Referer: http://www.hackr.jp/index.htm

该首部字段告知服务器请求的原始资源的 URI。

根据这个字段,服务器可以知道当前请求是从哪个地址跳转过来的,更多关于 Referer 的内容可以阅读阮一峰老师的博客:HTTP Referer 教程

2.5.18 TE
TE:gzip,deflate;q=0.5

该字段会告知服务器客户端能够处理的响应的传输编码方式及相对的优先级,其功能和 Transfer-Encoding 的功能类似。

2.5.19 User-Agent
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1

该字段会将创建请求的浏览器和用户代理名称的相关信息发送给服务器。当爬虫发起请求时,有可能会在该字段添加作者的地址。

值得一提的是有些网站会做出反爬虫策略,他们会验证 User-Agent 字段是否来自于浏览器,如果不是的话就会拒绝爬虫的请求;所以如果要想继续拿到想要的信息的话就会通过该字段将爬虫伪造成浏览器。

2.6 响应首部字段

响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求信息等。

2.6.1 Accept-Ranges
Accept-Ranges: bytes

该字段用于告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。当服务器能够处理客户端的范围请求时,其值为 bytes,反之为 none。

2.6.2 Age
ETag: 600

该首部字段告知客户端源服务器在多久之前创建了响应,字段的值的单位为秒。

若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次发起认证到再次认证完成的时间值。

2.6.3 ETag
ETag: "82e22293907ce725faf67773957acd12"

首部字段 ETag 能告知客户端实体标志。它是一种能够将资源以字符串形式做唯一性标志的方式。服务器会为每份资源分配对应的 ETag 值。

当资源更新时,ETag 值也要更新。完成 ETag 值时,并没有统一的算法规则,仅仅由服务器分配。

访问某个资源的 URI 一般不会发生改变,但是当资源本身发生了变化时,资源对应的 ETag 也会更新。

强 ETag 和弱 ETag

ETag 值有强弱之分,强 ETag 值不管资源发生多么细微的变化都会随之变化,而弱 ETag 值只有在资源发生了根本改变并产生差异时才会发生变化。

2.6.4 Location
Location: http://www.usagidesign.jp/sample.html

该首部字段可以将接受响应的客户端引导到某一个与其请求 URI 位置不同的资源。

基本上该字段会配合 3xx 重定向状态码一起使用。

2.6.5 Proxy-Authenticate
Proxy-Authenticate: Basic realm="Usagidesign Auth"

该首部字段会把代理服务器所要求的认证信息发送给客户端。

2.6.6 Retry After
Retry-After:120

该首部字段告知客户端在多久之后再次发起请求。该字段可以指定为具体的时间或者创建响应后的秒数。

2.6.7 Server

该首部字段会告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。

Server: Apache/2.2.17 (Unix)

2.6.8 Vary
Vary: Accept-Language

该首部字段可对缓存进行控制,源服务器会向代理服务器传达关于本地缓存使用方法的命令。

具体来说,该首部字段会指定一个其他的首部字段,比如上面的 Accept-Encoding,当指定字段的值未发生变化时,则使用缓存资源;如果指定字段的值发生了变化时,则需要向源服务器请求最新的资源。

这个字段可以指定 User-Agent,防止移动端浏览器访问页面时访问了 PC 端页面的缓存。

当该字段指定为 * 时,所有的请求都会被视为唯一的并且会被缓存。

2.6.9 WWW-Authenticate
WWW-Authenticate: Basic realm="Usagidesign Auth"

该首部字段用于 HTTP 访问认证。

2.7 实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间和实体相关的信息。

2.7.1 Allow
Allow:GET,HEAD

该首部字段用于通知客户端服务器能够支持的 HTTP 方法,当服务器接收到不支持的请求方法时,会返回 405 Not Allowed 状态码。

2.7.2 Content-Encoding
Content-Encoding:gzip

该首部字段会告知客户端对实体的主体部分所使用的内容编码格式。

具体编码格式可以参考 2.5.3 Accept-Encoding。

2.7.3 Content-Language
Content-Language:zh-CN

该首部字段用于通知客户端实体主体所使用的自然语言。

2.7.4 Content-Length
Content-Length:15000

该首部字段表明了实体主体的大小(单位是字节)。

如果对实体主体采用了内容编码传输时,不能再使用 Content-Length 首部字段。

2.7.5 Content-Location
Content-Location:http://www.hackr.jp/index-ja.html

该首部字段给出与报文主体相对应的 URI。当返回的页面内容与请求的实际对象不相同时,首部字段 Content-Location 会写明 URI。

2.7.6 Content-MD5
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==

客户端会对接收到的报文主体采用 MD5 算法进行散列计算,然后与 Content-MD5 的值进行比较以对接收到的主体内容进行完整性校验。

散列算法进行计算的做法主要用于防止传输内容被篡改,因为同一个输入通过散列算法计算以后得到的结果是相同的,不同的输入经过散列算法计算之后得到的结果基本不会重复。这也是许多提供资源下载的网站同时会给出资源对应 HASH 值的原因。

但是 Content-MD5 并不可靠,因为如果传输主体的内容可以被修改的话,Content-MD5 的值同样也可能被修改过,所以并不可靠。为了确保资源不被篡改,最好还是使用 HTTPS。

2.7.7 Content-Range
Content-Range: bytes 5001-10000/10000

针对范围请求,该首部字段告知客户端返回的响应的实体的哪些部分符合范围请求,单位为字节。

2.7.8 Content-Type
Content-Type: text/html; charset=UTF-8

该首部字段说明了实体主体内的媒体类型。

2.7.9 Expires
Expires: Wed, 04 Jul 2012 08:26:05 GMT

该首部字段将资源失效的日期告知客户端。

当首部字段 Cache-Control 有指定 max-age 指令时,会优先处理 max-age 指令。

2.7.10 Last-Modified
Last-Modified: Wed, 23 May 2012 09:59:55 GMT

该首部字段指明了资源的最终修改时间。

2.8 为 Cookie 服务的首部字段

Cookie 的工作机制是用户识别及状态管理

为 cookie 服务的首部字段:

首部字段名 说明 首部类型
Set-Cookie 开始状态管理所使用的 Cookie 信息 响应首部字段
Cookie 服务器接收到的 Cookie 信息 请求首部字段
2.8.1 Set-Cookie

当服务器开始准备管理客户端的状态时,会实现告知各种信息。

下面的表格列举了 Set-Cookie 的字段值。

属性 说明
NAME=VALUE 赋予 Cookie 的键和对应值
expires=DATE Cookie 的有效期
path=PATH 将服务器上的文件目录作为 Cookie 的适用对象(若不指定则默认为文档所在的文件目录)
domain=域名 作为 Cookie 适用对象的域名(若不指定则默认为创建 Cookie 的服务器的域名)
Secure 仅在 HTTPS 安全通信时才发送 Cookie
HttpOnly 加以限制,使 Cookie 不能被 JavaScript 所访问

下面详细讲讲 Cookie 的各个属性。

  • expires:该属性指定浏览器可以发送 Cookie 的有效期。当省略 expires 属性时,其有效期仅限于维持浏览器会话(Session)时间段内。这通常限于浏览器关闭之前。

    另外需要注意的是一旦 Cookie 从服务器端发送到客户端,服务器端就不存在可以显式删除 Cookie 的方法。只能通过覆盖已有的 Cookie 来达到删除的目的。

  • path:该属性用于限定指定 Cookie 的发送范围的文件目录。但是有其他办法可以避开这个限制,所以不要对它抱有太大期望。

  • domain:该属性的域名可做到与结尾匹配一致,比如指定 domain 为 example.com,此时 www.example.com 和 www2.example.com 也都可以访问 Cookie。所以不指定域名的情况下更加安全,因为默认只有当前响应的服务器的域名可以访问 Cookie。

  • secure:该属性限制 Web 页面仅在 HTTPS 安全连接时才发送 Cookie。当省略该属性时,HTTP 和 HTTPS 协议的指定域名都可以访问 Cookie。

  • HttpOnly:该属性使得 JavaScript 无法对 Cookie 进行读取操作。

2.8.2 Cookie
Cookie:status=enable

首部字段 Cookie 会告知服务器,当客户端想要获得 HTTP 状态管理的支持时,就会在请求中包含从服务器中获取到的 Cookie。

2.9 其他首部字段

HTTP 首部字段是可以自行扩展的,所以在 Web 服务器和浏览器的应用上,会出现一些非标准的首部字段。

下面是比较常用的非标准首部字段:

  • X-Frame-Options
  • X-XSS-Protection
  • DNT
  • P3P
2.9.1 X-Frame-Options
X-Frame-Options: DENY

该首部字段属于 HTTP 响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是防止点击劫持攻击(clickjacking)。

此处的 Frame 包括 iframe、frame、object 等标签

该字段可以指定三类值:

  • DENY:拒绝被嵌套到 Frame,即使是相同域名下的页面也不行
  • SAMEORIGIN:该页面只可以被嵌入到相同域名页面的 Frame 中
  • ALLOW-FROM uri:表示可以在指定来源的页面中被嵌套
2.9.2 X-XSS-Protection

该字段属于响应首部,是针对跨域脚本攻击的一种策略,用于控制浏览器 XSS 防护机制的开关。

该字段可以设置一下了两个值:

  • 0:将 XSS 过滤设置成无效状态
  • 1:将 XSS 过滤设置成有效状态
2.9.3 DNT
DNT:1

该首部字段属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简称,表示拒绝个人信息被收集。

0 表示同意被追踪,1 表示拒绝被追踪。

2.9.4 P3P

该首部字段属于响应首部,通过利用 P3P 技术让网站上的个人隐私变成仅供程序可理解的形式。