http 头部详解
一. 通用头部字段 (General Header Fields)
该字段在请求头和响应头都会使用到,下方是常用的通用头部字段:
1、Cache-Control
用来操作缓存的工作机制,下方截图响应头中的的 Cache-Control 的参数为 private 和 max-age=10。private 缓存是私有的,仅像特定用户提供相应的缓存信息。如果是 public,那么就意味着可向任意方提供相应的缓存信息。max-age = 10 表示缓存有效期为 10 秒。从下方的 Expires(过期时间) 和 Last-Modified(最后修改时间) 就可以看出,这两者之间的差值正好是 10 秒。
该字段还可以对应其他的参数:
• no-cache:如果是客户端的话,说明客户端不会接收缓存过的响应,要请求最新的内容。而服务器端则表示缓存服务器不能对相应的资源进行缓存。
• no-store:表示缓存不能在本地存储。
• max-age:该参数后方会被赋值上相应的秒数,在请求头中表示如果缓存时间没有超过这个值就返回给我。而在响应头中时,则表示资源在缓存服务器中缓存的最大时间。
• only-if-cached:表示客户端仅仅请求缓存服务器上的内容,如果缓存服务器上没有请求的内容,那么返回 504 Gateway Timeout。
• must-revalidata:表示缓存服务器在返回资源是,必须向资源服务器确认其缓存的有效性。
• no-transform:无论请求还是响应,都不能在传输的过程中改变报文体的媒体类型。
2、Connection
该字段可以控制不转发给代理服务器的首部字段以及管理持久连接,下方这个响应报文头中的 Connection 就是用来管理持久连接的,其参数为 keep-alive,就是保持持久连接的意思。可以使用 close 参数将其关闭。
3、Transfer-Encoding
该字段表示报文在传输过程中采用的编码方式,在 HTTP/1.1 的报文传输过程中仅对分块编码有效。下方这个截图就是 Transfer-Encoding 在 Response Header 中的使用,后边根的 chunked(分块) 的参数,说明报文是分块进行传输的。
4、Via
该字段是为了追踪请求和响应报文测传输路径,报文经过代理或者网关是会在 Via 字段添加该服务器的信息,然后再进行转发。
二. 请求头部字段 (Request Header Fields)
顾名思义,请求头部字段当然是在请求头中才使用的字段。该字段用于补充请求的附加信息,客户端信息等。接下来将给出常用而且比较重要的几个请求头部字段。
1 Accept
该字段可通知服务器用户代理能够处理的媒体类型以及该媒体类型对应的优先级。媒体类型可使用“type/subtype”这种形式来指定,分号后边紧跟着的是该类型的优先级。如下所示。
2 Accept-Encoding
该字段用来告知服务器,客户端这边可支持的内容编码以及相应内容编码的优先级, 下方就是 Accept-Encoding 的用法。gzip 表示由文件压缩程序 gzip(GNU zip) 生成的编码格式。compress 表示 UNIX 文件压缩程序 compress 生成的编码格式。deflate 表示组合使用 zlib 格式以及有 deflate 压缩算法生成的编码格式。identity 表示不执行压缩或者使用一致的默认编码格式。
3 Accept-Language
该字段用来告知服务器,客户端可处理的自然语言集,以及对应语言集的优先级。以下方的截图为例,Accept-Language 后方跟了三个属性,分别是“zh-CN”, “zh;q=0.8”,“en;q=0.6”。也就是说客户端可处理三种自然预言集,zh-CN,其优先级是 1(最高)。第二种是 zh ,其优先级是 0.8,次之。第三个是 en,优先级为 0.6,优先级在三者之间最低。
4 Authorization
用来告知服务器用户端的认证信息,下方就是连接公司内部 SVN 系统时需要认证时的请求头部信息。
如果你没有填写认证信息的话,那么就会返回 401 Unauthorized。如下所示:
5 If-Match 与 If-None-Match
上面这两个请求头部字段都是带有逻辑判断的,从上面的英文我们不难看出两者恰好相反。两者后方都跟着串字符串,如 If-Match “xcsldjh49773hce”, 后边这个字符的匹配对象是 ETag(稍后会介绍)。If-Match 的请求是如果后方的字符串与 ETag 相等则服务器端进行请求,否则不进行处理。If-None-Match 是 If-Match 的非操作,同样是匹配 ETag, 如果 Etag 没有匹配成功就处理请求,否则不处理。
6 If-Modified-Since 与 If-Unmodified-Since
If-Modified-Since 也是带有逻辑判断的请求头部字段,该字段后方跟的是一个日期,意思是在该日期后发生了资源更新,那么服务器就会处理该请求。If-Unmodified-Since 就是 If-Modified-Since 的非操作。
7 If-Range
if-Range 字段后方也是跟的 Etag, 该字段要结合着 Range 字段进行使用。其所代表的意思就是如果 Etag 匹配成功,请求的内容就按照 Range 字段所规定的范围进行返回,否则返回全部的内容。用法如下所示:
If-Range: “etag_code”
Range: bytes=1000-5000
8 Referer
其实 Referer 是一个错误的拼写,但是一直在使用。正确的英文单词应该是 Referrer(此处可翻译为: 来历、来路)。Referer 字段后方跟的是一个 URI, 该 URI 就是发起请求的 URI,具体如下所示:
9 User-Agent
该字段会将请求方的浏览器和用户代理名称等信息传达给服务器。下方就是从我当前笔记本的 Chrome 浏览器请求网络时的 User-Agent 信息。
三. 响应头部字段 (Request Header Fields)
聊完请求报文头部字段后,我们接下来来聊一下响应报文头部字段。响应头是由 Server 向 Client 返回响应报文中使用的头部信息。用户补充响应的附加信息、服务信息等。下方是几个常见响应头部字段。
1 Accept-Ranges
该字段用来告知客户端服务器那边是否支持范围请求(请求部分内容,请求头中使用 Range 字段)。Accept-Ranges 的值为 bytes 时,就说明服务器支持范围请求,为 none 时,说明服务器不支持客户端的范围请求。下方是博客园的页面的加载,从下方可以看出是支持范围请求的,如下所示:
2 Age
该字段告知客户端,源服务器在多久前创建了该响应。
3 Etag
Etag 是服务器当前请求的服务器资源(图片,HTML 页面等)所对应的一个独有的字符串。不同资源间的 Etag 是不同的,当资源更新时 Etag 也会进行更新。
所以结合着请求头中的 If-Match 等逻辑请求头,可以判断当前 Client 端已经加载的资源在服务器端是否已经更新了。当初次请求一个资源,如图片时,我们可以将其 Etag 进行保存,在此请求时,可放在 If-None-Match 后方,进行资源更新。如果服务器资源并未修改,就不对该请求做出响应。下方就是网页中某张图片对应着的 Etag,如下所示。
4 Location
Location 字段一般与重定向结合着使用。下方是我访问“www.baidu.com/hello”这个连接的响应报文。因为服务器上并没有 /hello 这个资源路径,所以给我重定向了 error.html 页面,这个重定向的 URL 就存储在 Location 字段中,如下所示:
5 Server
该响应字段表明了服务器端使用的服务器型号,下方是博客园某张图片的响应头,使用的 Web 服务器是 Tengine, Tengin 是淘宝发起的 Web 服务器项目,是基于 Nginx 的,关于 Tengin 的相关内容,请自行 Google 吧。
6 Vary
Vary 可对缓存进行控制,通过该字段,源服务器会向代理服务器传达关于本地缓存使用方法的命令。下方就是 Vary 的使用,Vary 后方的参数是 Accept-Encoding。其意思是返回的缓存要以 Accept-Encoding 为准。当请求的 Accept-Encoding 的参数与缓存内容的 Accept-Encoding 参数一致时就返回缓存内容,否则就请求源服务器。
7 WWW-Authenticate
该字段用于 HTTP 的访问认证,在状态码 401 Unauthorized 中肯定带有此字段,该字段用来指定客户端的认证方案(Basic 或者 Digest)。参数 realm 的字符串是为了辨别请求 URL 指定资源所受到的保护策略。如下所示:
四、实体头部字段(Content Header Fields)四、实体头部字段(Content Header Fields)
接下来我们就来聊聊常见的实体头部字段,实体头部字段是报文实体所使用的头部,用来补充与报文实体相关的信息。
1 Allow
该字段用于服务器通知客户端服务器这边所支持的所有请求方法(GET、POST 等)。如果服务器找不到客户端请求中所提到的方法的话,就会返回 405 Method Not Allowed,于此同时还会把所有能支持的 HTTP 方法写入到首部字段 Allow 后返回。
Allow : GET, POST, HEAD, PUT, DELETE
2 Content-Encoding
该字段用来说明报文实体的编码方式,下方这段报文头中的 Content-Encoding 的参数为 gzip,说明是使用 gzip 对报文实体进行压缩的。
3 Content-Language
该字段表示报文实体使用的自然语言,使用方式如下所示:
Content-Language: zh-CN
4 Content-Length
顾名思义,该字段用来指定报文实体的字节长度,如下所示:
5 Content-MD5
该字段中存储的是报文实体进行 MD5 加密然后再使用 Base64 进行编码的字符串。客户端收到响应报文后,可以对报文实体进行 MD5 加密,然后再对其进行 Base64 编码,然后与 Content-MD5 中的字符串进行比较来确定报文是否进行修改,可以说这是一个简单的验签功能。但是此方法并不能确定报文是否被修改了,因为 Content-MD5 这个值也有可能被篡改。
五、Cookie 相关的头部字段
因为 HTTP 协议本身是无状态的,在 Web 站点中使用 Cookie 来管理服务器与客户端之间的状态。解析来我就来介绍一下 Cookie 相关的头部字段。
1、Set-Cookie
响应报文中会使用到该字段。当服务器准备开始管理客户端的状态时,会事先告知其各种信息。下方字段是登录知乎时所返回的所要设置的 Cookie 信息。接下来我们就要对这串 Cookie 信息进行解析。
• 键值对:在 Set-Cookie 字段中,“z_co=Mi4……”这就是要存入 Cookie 中的信息,当然可以是多个键值对,中间使用逗号进行分割即可。
• Domain:然后是 Domain 属性,由下方不难看出,Domain 中存储的就是 Cookie 适用对象的域名,若不指定 Domain 的值,那么默认就是创建 Cookie 的服务器的域名。
• expire:该字段属性的值是一个时间,也就是 Cookie 的有效期,若不指定该属性的值,默认就是当前会话有效,关闭浏览器 Cookie 即失效。
• httponly:设置该属性的目的是让 JavaScript 脚本无法获取 Cookie,其主要目的是防止跨站脚本攻击对 Cookie 信息的窃取。
• path: 用于限制指定 Cookie 的发送范围的文件目录。
• Secure:仅在 HTTPS 安全通信时才会发送 Cookie。
2.Cookie
请求报文头中会使用该字段,用于将本地存储的 Cookie 信息发送给服务端。下方就是知乎上每次请求文章所带有的 Cookie 信息,当然下方只是部分信息,但是我们还是从中可以找到之前我们存储的“z_co=Mi4……”这个键值对的。
其他比较常见而且比较简单的头部字段就不做过多赘述了