图解HTTP读书笔记(六)

图解HTTP读书笔记(六)

第六章 HTTP首部

HTTP报文首部

HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。
- 请求报文
在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。

image

下面的示例是访问http://hackr.jp时,请求报文的首部信息。
image

  • 响应报文

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

image

以下示例是之前请求访问http://hackr.jp时,返回的响应报文的首部信息。

image

HTTP首部字段
  • HTTP首部字段信息和结构
    HTTP首部字段是构成HTTP报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,起到传递额外重要信息的作用。使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容

结构:

对应一个值:

首部字段名:字段值

eg:
Content-Type:text/html

对应多个值:

首部字段名:字段值,...,字段值

Keep-Alive:timeout=15,max=100

若HTTP报文首部中出现了两个或两个以上具有相同首部字段名时会怎样?

这种情况在规范未明确,根据浏览器内部处理逻辑的不同。结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。

  • 4种HTTP首部字段类型
    • 通用首部字段:请求报文和响应报文两方都会使用的首部。
    • 请求首部字段:客户端向服务器发送请求报文时使用的首部。补充了请求的附加内容,客户端信息、响应内容相关的优先级等信息。
    • 响应首部字段:从服务器向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息
    • 实体首部字段:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新的时间等与实体有关的信息
  • HTTP/1.1首部字段一览表
    HTTP/1.1规范定义了如下47种首部字段。

image

image

image

image

  • 非HTTP/1.1首部字段

在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。还有Cookie、Set-Cookie和Content-Disposition等在其他RFC中定义的首部字段,它们的使用频率也很高。

这些非正式的首部字段统一归纳在RFC4229HTTP 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个首部字段之外,其他的都属于端到端首部。

image

HTTP/1.1通用首部字段
  • Cache-Control

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

Cache-Control指令一览表

image

image

Cache-Control几个比较常用的指令

  1. no-cache:目的是为了防止从缓存中返回过期的资源。

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

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

  1. no-store:当使用no-store指令时,暗示请求(和对应的响应)或响应中包含机密信息。因此,该指令规定缓存不能再本地存储请求或响应的任一部分。

注意::no-cache与no-store的区别:
no-cache:代表不缓存过期的资源。缓存会向源服务器进行有效期确认后处理资源。
no-store:才是真正的不进行缓存。

  • Connection:Connection首部字段具备如下两个作用。
    一是:控制不再转发给代理的首部字段(即Hop-by-hop首部)。二是:管理持久连接。

    HTTP/1.1版本的默认连接都是持久化连接。为此,客户端会在持久连接上连续发送请求。当服务器想明确断开连接时,则指定Connection首部字段的值为close。

image

HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。

image

  • Date:首部字段Date表明创建HTTP报文的日期和时间。

  • Pragma:是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。

规范定义的形式唯一,如:Pragma:no-cache

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

image

以上用例中,指定首部字段Trailer的值为Expires,在报文主体之后(分块长度0之后)出现了首部字段Expires。

  • Transfer-Encoding:首部字段Tranfer-Encoding规定了传输报文主体时采用的编码方式。HTTP/1.1的传输编码方式仅对分块传输编码有效。

image

以上用例中,正如首部字段Transfer-Encoding中指定的那样,有效用分块传输编码,且分别被分成3312字节和914字节大小的分块数据。

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

image

上图用例中,首部字段Upgrade指定的值为TLS/1.0。请注意此处两个字段首部字段的对应关系,Connection的值被指定为Upgrade。Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。因此,使用首部字段Upgrade时,还需要额外指定Connection:Upgrade。

对于附有首部字段Upgrade的请求,服务器可用101Switching Protocols状态码作为响应返回。

  • Via:使用首部字段Via是为了追踪客户端和服务端之间的请求和响应报文的传输路径。

报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。

首部字段Via不仅用于追踪报文的转发,还不可避免请求回环的发生,所以必须在经过代理时附加该首部字段的内容。

image

Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。

  • Warning:HTTP/1.1的Warming首部是从HTTP/1.0的响应首部(Retry-After)演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。

image

HTTP/1.1中定义了7种警告。警告码对应的警告内容仅推荐参考。另外,警告码具备扩展性,今后有可能追加新的警告码。

image


HTTP请求首部字段

请求首部字段是从客户端往服务端发送请求报文中使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。

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

image

下面我们举几个媒体类型的例子。

1. 文本文件
    text/html,text/plain,text/css...
    application/xhtml+xml,application/xml...
2. 图片文件
    image/jpeg,image/gif,image/png...
3. 视频文件
    video/mpeg,video/quicktime...
4. 应用程序使用的二进制文件
    application/octet-stream,application/zip...

若想要给显示媒体类型的优先级,则使用q=来额外表示权重值,用分号(;)进行分隔。权重值q的范围是0-1(可精确到小数点后3位),且1为最大值。

当服务器提供多种内容时,将会首先返回权重最高的媒体类型。
  • Accept-Charset:首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先级顺序。另外,可一次性指定多种字符集。与首部字段Accept相同的是可用权重q值来表示相对优先级。

image

该首部字段应用于内容协商机制的服务器驱动协商。

  • Accept-Encoding:首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。

内容编码的例子:

1. gzip:由文件压缩程序gzip(GNU zip)生成的编码格式(RFC1952),采用Lemepl-Ziv算法及32位循环冗余校验(CRC32)。

2. compress:由UNIX文件压缩程序compress生成的编码格式,采用Lemepel-Zip-Welch算法。

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

4.identity:不执行压缩或不会变化的默认编码格式。

采用权重q值来表示相对优先级,这点与首部字段Accept相同。另外也可以使用*作为通配符,指定任意的编码格式。

  • Accept-Language:用来告知服务器用户代理能够处理的自然语言集(中文或英文等),以及自然语言集的相对优先级,可一次指定多种自然语言集。

image

  • Authorization:用来告知服务器,用户代理的认证信息(证书值)。通常,想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,把首部字段Authorization加入请求中。共用缓存在接收到含有Authorization首部字段的请求时的操作处理会略有差异。

  • Expect:客户端使用首部字段Expect来告知服务器,期望出现的某种特定行为。因为服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码417Expection Failed。

客户端可以利用该首部字段,写明所期望的扩展。虽然HTTP/1.1规范只定义了100-continue(状态码100Continue之意)。

  • From:用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能包含From首部字段。

  • Host:会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段再HTTP/1.1规范内唯一一个必须被包含在请求内的首部字段。

首部字段Host和单台服务器分配对个域名的虚拟主机的工作机制有很密切的关联,这是首部字段Host必须存在的意义。(详情请看第五章)

  • If-Match:形如:If-xxx这种形式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。

image

首部字段If-Match,属附带条件之一,他会告知服务器匹配资源所用的实体标记(ETag)值。这时的服务器无法使用弱ETag值。(详情参考ETag)

服务器会比对If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求,反之,则返回状态码412Precondition Failed的响应。

还可以指定*号指定If-Match的字段值,针对这种情况,服务器将会忽略ETag的值,只要资源存在就处理请求。

  • If-Modified-Since:他会告知服务器若有If-Modifoed-Since字段值早于资源的更新时间,则希望能处理该请求。而在指定If-Modified-Since字段值的日期时间之后,如果请求的资源都没有更新过,则返回状态码304 Not Modified响应。

image

If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段Last-Modified来确定。

  • If-None-Match:它和If-Match作用相反。用于指定If-None-Match字段值的实体标记(ETag)值与请求资源的ETag不一致时,它就告知服务器处理该请求。

image

在GET和HEAD方法中使用首部字段If-None-Match可获得最新的资源。因此,这与使用首部字段If-Modified-Since时有点类似。

  • If-Range:他告知服务器若指定的If-Range字段值(ETag值或者时间)和请求资源的ETag值或时间一致时,则作为范围请求处理。反之,则返回全体资源。

image

如果不使用If-Range发送请求,当服务器端的资源更新,可能导致客户端持有的资源无效,这时,服务器会暂且以状态码412Precondition Failed作为响应返回,其目的是催促客户端再次发送请求,这样就比使用If-Range比起来,需要花费两倍的功夫了。

image

  • If-Unmodified-Since:和If-Modifitied-Since的作用是相反的。作用是告知服务器,指定的请求资源只有在字段值内指定的日期时间后,未发生更新的情况下,才能处理请求。如果能在指定日期时间后发生更新,则以状态码412Precondition Failed作为响应返回。

  • Max-Forwards
    image

通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以上十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards值为0的请求时,则不再进行转发,而是直接返回响应。

image

  • Proxy-Authorization:接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。

这个行为是与客户端和服务器之间的HTTP访问认证相类似的,不同之处在于,认证行为发生在客户端与代理之间。

  • Range:对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。

eg:Range:bytea=5001-10000(表示请求从5001字节到10000字节的资源)。

接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码为206Partial Content的响应。无法处理该范围请求时,则会返回状态码200OK的响应及全部资源。

  • Referer:首部字段Referer会告知服务器请求的原始资源的URI。

image

出于安全性考虑,不发送该首部字段,因为原始资源的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则有可能导致保密信息泄露。

  • TE:首部字段TE会告知服务器客户端能够处理的响应的传输编码方式及相对优先级。他和首部字段Accept-Encoding的功能很像,但是用于传输编码。

eg:

TE:gzip,deflate;q=0.5

首部字段TE除了指定传输编码之外,还可以指定伴随trailer字段的分块传输编码的方式。应用后者时,只需把trailers赋值给该字段。

TE:trailers
  • User-Agent:首部字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。

image

由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮箱地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。


响应首部字段

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

  • Accept-Ranges:首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端的某个部分的资源。

可指定的字段值有2种,可处理范围请求时指定其为bytes,反之指定为none。

image

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

image

若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证完成的时间值。代理创建的响应必须加上首部字段Age。

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

image
另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。

image

资源被缓存时,就会被分配唯一性的标识。例如,当使用中文版浏览器访问google时,返回中文版的资源,如果使用英文版的浏览器访问时,返回英文版的资源,两者uri相同,所以仅凭uri指定缓存的资源是相当困难的。若在下载过程中出现连接中断和再连接的情况,都会依照ETag值来指定资源。

强ETag值和弱ETag值

强ETag:不论实体发生多么细微的变化都会改变其值。

弱ETag:只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这是会在字段值最开始及处附加W/。

ETag:W/"usagi-1234"
  • Location:使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。

基本上,该字段会配合3xx:Redirection的响应,提供重定向的URI。

几乎所有的浏览器在接受到包含首部字段Location的响应后,都会强制性的尝试对以提示的重定向资源的访问。

image

  • Proxy-Authenticate:首部字段Proxy-Authenticate会把代理服务器所要求的认证信息发送给客户端。
Proxy-Authenticate:Basic realm="Usagidesign Auth"

它与客户端和服务器之间的HTTP访问认证的行为相似,不同之处在于,其认证行为是在客户端与代理之间进行的。而客户端与服务器之间进行认证是,首部字段WWW-Authorization有着相同的作用。有关HTTP访问认证,后面会详细说明。

  • Retry-After:首部字段Retry-After告知客户端应该在多久之后再次发送请求。主要配合状态码503Service Unavailable响应,或3xx Redirect响应一起使用。
Retry-After:120

字段值可以指定为具体的日期和时间(Wed,04 Jul 2012 06:34:24 GMT等格式),也可以是创建响应后的秒数。

  • Server:首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序信息。不单单会标出服务器上的软件应用名称,还可以包括版本号和安装时启用的可选项。
Server:Apache/2.2.6(Unix) PHP/5.2.5
  • Vary:首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。

从代理服务器接收到源服务器返回包含Vary指定项的响应之后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。

image

  • WWW-Authenticate:首部字段WWW-Authenticate用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic或是Digest)和带参数提示的质询(challenge)。状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate。
WWW-Authenticate:Basic realm="Usagidesign Auth"

实体首部字段

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

  • Allow:首部字段Allow用于通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器接收不支持的HTTP方法时,会以状态码405 Method Not Allow作为响应返回。同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。

  • Content-Encoding:首部字段Content-Encoding会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。

主要采用以下4种内容编码的方式:

1. gzip
2. compress
3. deflate
4. identity
  • Content-Language:首部字段Content-Language会告知客户端,实体主体使用的自然语言(指中文或英文等语言)。
Content-Language:zh-CN
  • Content-Length:首部字段Content-Length表明了实体主体部分的大小(单位字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。
Content-Length:10000
  • Content-Location:首部字段Content-Location给出与报文主体部分相对应的URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。

比如,对于使用首部字段Accept-Language的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI.

  • Content-MD5:首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。

image

对报文主体执行MD5算法获得的值,再通过base64编码后将结果写入Content-MD5字段值。由于HTTP首部字段无法记录二进制值,所以要通过base64编码处理。

  • Content-Range:针对范围请求,返回响应时使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。

image

  • Content-Type:首部字段Content-Type说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/ subtype形式赋值。
Content-Type:text/html;charset=UTF-8
  • Expires:首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。

image

源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。

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

  • Last-Modified:首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。

但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。

为Cookie服务的首部字段

image

  • Set-Cookie:

image

1. expires属性
    Cookie的expires属性指定浏览器可发送Cookie的有效期。
    当省略expires属性时,其有效期仅限于维持浏览器会话(Session)时间段内。这通常限于浏览器应用程序被关闭之前。
    另外,一旦Cookie从服务器发送至客户端,服务器就不能显示删除Cookie,但可通过覆盖已过期的Cookie。
2.path属性
Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。
3.domain属性
通过Cookie的domain属性指定的域名可做到与结尾匹配一致。比如:当指定example.com后,除了example.com以外www.example.com和www2.example.com等都可以发送Cookie。
因此,除了针对具体指定的多个域名发送Cookie之外,不指定domain属性显的更安全。
4.secure属性
Cookie的secure属性用于限制web页面仅在HTTPS安全连接时,才可以发送Cookie。
eg:Set-Cookie:name=value;secure
5.HttpOnly属性
Cookie的HttpOnly属性是Cookie的扩展功能,它使javascript脚本无法获得Cookie.其主要目的为防止跨脚本攻击(Cross-sitescripting,XSS)对Cookie的信息窃取。
eg:Set-Cookie:name=value;HttpOnly
通过上述设置,通常Web页面内还可以对Cookie进行读取操作。但使用javascript的document.cookie就无法读取附加HttpOnly属性后的Cookie的内容了。因此,也就无法在XSS中利用javascript劫持Cookie了。
  • Cookie:首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。
Cookie:statue-enable
其他首部字段

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

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

首部字段X-Frame-Options有以下2个可指定的字段值:

1.DENY:拒绝
2.SAMEORIGIN:仅同源域名下的页面(Top-level-browsing-context)匹配时许可。
  • X-XSS-Protection:首部字段X-XSS-Protection属于HTTP响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器XSS防护机制的开关。

首部字段X-XSS-Protection可指定的字段值如下:

0:将XSS过滤设置成无效状态
1:将XSS过滤设置成有效状态
X-XSS-Protection:1
  • DNT:首部字段DNT属于HTTP请求首部,其中DNT是Do Not Track的简称。意思是拒绝个人信息被收集,表示拒绝被精准广告追踪的一种方法。

DNT可指定的字段值如下:

0:同意被追踪
1:拒绝被追踪

由于首部字段DNT的功能具备有效性,所以web服务器需要对DNT做对应的支持。

  • P3P:首部字段P3P属于HTTP相应首部,通过P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,可以让web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值