《图解HTTP》 |笔记(上)
一、了解web及网络基础
1.1 使用HTTP访问web
根据Web浏览器地址栏中指定的URL,Web浏览器从Web服务器端获取文件资源(resource)等信息,从而显示出Web页面。Web使用HTTP(HyperText Transfer Protocol,超文本传输协议)协议作为规范,完成从客户端到服务器端等一系列运作流程。可以说,Web是建立在HTTP协议上通信的。
-
什么是协议?
计算机与网络设备要相互通信,双方就必须基于相同的方法。比如,如何探测到通信目标、由哪一边先发起通信等规则。这些规则就称为协议(protocol)
-
什么是TCP/IP,跟HTTP有什么关系?:
把与互联网相关联的协议集合起来总称为TCP/IP。HTTP属于它内部的一个子集:
1.2 TCP/IP的分层管理
-
应用层:决定了向用户提供应用服务时通信的活动。TCP/IP协议族内预存了各类通用的应用服务:
- FTP(File TransferProtocol,文件传输协议)
- DNS(Domain Name System,域名系统)
- HTTP协议
-
传输层:给应用层提供处于网络连接中的两台计算机之间的数据传输。在传输层有两个性质不同的协议:
- TCP(Transmission Control Protocol,传输控制协议)
- UDP(User Data Protocol,用户数据报协议)
-
网络层:处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径到达对方计算机,并把数据包传送给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
-
链路层:用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)
1.3 TCP/IP通信传输流
利用TCP/IP协议族进行网络通信时,发送端从应用层往下走,接收端则往应用层往上走。
首先,作为发送端的客户端在应用层(HTTP协议)发出一个HTTP请求。接着在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层;然后在网络层(IP协议)增加作为通信目的地的MAC地址后转发给链路层。这样,就成功向网络发送通信请求了。
接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的HTTP请求。
-
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。
-
接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
1.4 与HTTP关系密切的协议
IP协议
位于网络层,作用是把各种数据包传送给对方。实现传送需要三个重要条件:
1. IP地址:节点被分配的地址,可变
2. MAC地址:网卡所属的固定地址
3. ARP协议:解析地址。根据IP地址反查出对应的MAC地址
IP间的通讯依赖MAC地址,在网络上,通信的双方通常是经过多台计算机和网络设备的MAC地址来搜索下一个中转目标。
TCP协议
位于传输层,提供可靠的字节流服务,并且确认数据是否成功送达到对方。(字节流服务(Byte Stream Serviee)是为了方便传输,将大块数据分割成以报文段(segment)为单位的数据包进行管理的服务)
为了准确无误将数据送达目标,TCP协议采用了三次握手(three-way handshaking)策略。握手过程使用了TCP标志:SYN(synchronize)和ACK(acknowledgement)。握手过程如下:
1. 发送端发送一个带有`SYN`标志的数据包给对方
2. 接收端收到后,回传一个带有`SYN/ACK`标志的数据包以示传达确认信息
3. 发送端再回传一个带有`ACK`标志的数据包,代表握手结束
DNS协议
位于应用层,实现域名与IP地址之间的解析转换。计算机既可以被赋予IP地址,也可以被赋予主机名和域名,比如www.example.com。为了让计算机去理解这些名称,就需要用到DNS协议。
整个过程
1.5 URI和URL
- URL(Uniform Resource Locator,统一资源定位符):使用Web浏览器等访问Web页面时需要输入的网页地址,如
http://hackr.jp/
- URI(Uniform Resource Identifier,统一资源标识符):用字符串标识某一互联网资源。URL只表示资源的地点,而URI表示对应地点中的资源
- Uniform:规定统一的格式。可方便处理多种不同类型的资源,而不用根据上下文环境来识别资源指定的访问方式。也称协议方案。
- Resource:是“可标识的任何东西”。不仅是文档文件,图像或服务(例如当天的天气预报)等能够区别于其他类型的,全都可作为资源。
- Identifier:表示可标识的对象,也称为标识符
采用HTTP协议时,协议方案就是http。除此之外,还有ftp、mailto、telnet、file等。下面是几个几种URI例子:
二、HTTP协议
2.1 示例
HTTP协议规定,请求从客户端发出,最后由服务端响应该请求并返回。即先从客户端开始建立通信。
下面是一个客户端发送给某个http服务端的请求报文中的内容:
GET /index.htm HTTP/1.1
Host:hackr.jp
GET
表示请求访问服务器的类型/index.htm
指明了请求访问的资源对象,也叫请求URI(request-URI)HTTP/1.1
指明了HTTP版本号Host:hackr.jp
表示请求的服务器地址
2.2 报文种类
用于HTTP协议交互的信息被称为HTTP报文。报文的种类可分为:
-
请求报文:请求端(客户端)的HTTP报文。请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成
-
响应报文:响应端(服务器端)的HTTP报文。响应报文是由协议版本、状态码、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成
2.3 报文结构
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f605bebf63d94810baa3033e164b24c3~tplv-k3u1fbpfcp-watermark.webp)
-
报文首部:服务器端或客户端需处理的请求或响应的内容及属性
-
报文主体:应被发送的数据
什么是实体主体?
HTTP报文主体用于传输请求或响应的实体主体。通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生变化,才导致它和报文主体产生差异。
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7e0c1a5594a347b8aa3e7ed6b16d2fd5~tplv-k3u1fbpfcp-watermark.webp)
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c7c724de7e614795bb3780a667136240~tplv-k3u1fbpfcp-watermark.webp)
2.4 报文实例
请求行:包含用于请求的方法,请求URI和HTTP版本
状态行:包含表明响应结果的状态码,原因短语和HTTP版本
首部字段:包含表示请求和响应的各种条件和属性的各类首部。一般有4种分别是:通用首部、请求首部、响应首部和实体首部
其他:可能包含HTTP的RFC里未定义的首部(Cookie等)
2.5 请求URI
URI写法
当客户端请求访问资源而发送请求时,写法有两种:
-
在首部字段Host中写明网络域名或IP地址
GET /index.htm HTTP/1.1 Host:hackr.jp
-
写成完整的请求URI:
GET http://hackr.jp/index.htm HTTP/1.1
URI格式
如果要表示指定的URI,要使用涵盖全部必要信息的绝对URI、绝对URL以及相对URL。相对URL是指从浏览器中基本URI处指定的URL,形如 /image/logo.gif。以下是绝对URI的格式:
-
登录信息(认证):指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份认证)。此项是可选项。
-
服务器地址:使用绝对URI必须指定待访问的服务器地址。地址可以是类似hackr.jp这种DNS可解析的名称,或是192.168.1.1这类IPv4地址名,还可以是[0:0:0:0:0:0:0:1]这样用方括号括起来的IPv6地址名。
-
服务器端口号:指定服务器连接的网络端口号。此项也是可选项,若用户省略则自动使用默认端口号。
-
带层次的文件路径:指定服务器上的文件路径来定位特指的资源。这与UNIX系统的文件目录结构相似。
-
查询字符串:针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。此项可选。
-
片段标识符:使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个位置)。但在RFC中并没有明确规定其使用方法。该项也为可选项。
2.6 请求方法
GET
请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。
POST
传输实体的主体。
PUT
传输文件。
HTTP/1.1的PUT方法自身不带验证机制,所以任何人都可以上传文件,因此一般的Web网站不使用该方法。一般需要配合Web应用程序的验证机制,或架构设计采用REST(Representational State Transfer,表征状态转移)标准的同类Web网站,才可能会开放使用PUT方法。(DELETE方法同理)
DELETE
删除文件。
HEAD
获得报文首部。与GET方法一样,只是不返回报文主体部分。主要用于确认URI的有效性及资源更新的日期时间等。
OPTIONS
询问支持的方法。
TRACE
追踪路径。让Web服务器端将请求通信环返回给客户端。
发送请求时,在Max-Forwards
首部字段中填入数值,每经过一个服务器端就将该数字减1,当数值刚好减到0时,就停止继续传输,最后接收到请求的服务器端则返回状态码200 OK
的响应。客户端通过TRACE
方法可以查询发送出去的请求是怎样被加工修改/篡改的。它容易引发XST(Cross-SiteTracing,跨站追踪)攻击。
CONNECT
要求用隧道协议连接代理。
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(Secure Sockets Layer,安全套接层)和TLS(TransportLayer Security,传输层安全)协议把通信内容加密后经网络隧道传输。格式如下:
CONNECT 代理服务器名:端口号 HTTP版本
2.7 Cookie
HTTP是无状态协议。HTTP协议不对请求和响应之间的通信状态进行保存。为了实现状态保存,需要引用Cookie技术
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
三、HTTP传输
3.1 持久连接
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接
而当文档中包含大量图片时:
为解决上述TCP连接的问题,HTTP/1.1和一部分的HTTP/1.0想出了持久连接(HTTP Persistent Connections,也称为HTTP keep-alive或HTTP connectionreuse)的方法。只要任意一端没有明确提出断开连接,则保持TCP连接状态。持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。
3.2 管线化
从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。
3.3 传输编码
HTTP在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多的CPU等资源。
3.4 内容编码
HTTP协议具有内容编码的功能。内容编码可以压缩报文实体内容的大小,加快响应的速度。内容编码后的实体由客户端接收并负责解码。常用的内容编码有:gzip(GNU zip)、compress(UNIX系统的标准压缩)、deflate(zlib)、identity(不进行编码)
3.5 分块传输编码
在HTTP通信过程中,请求的编码实体资源在传输完成之前,浏览器无法显示请求页面。
在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。这种把实体主体分块的功能称为分块传输编码(Chunked Transfer Coding)
分成的每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标记。使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编码前的实体主体。HTTP/1.1中存在一种称为传输编码(Transfer Coding)的机制,它可以在通信时按某种编码方式传输,但只定义作用于分块传输编码中。
3.6 多部分对象集合
![]()
发送邮件时,我们可以在邮件里写入文字并添加多份附件。这是因为采用了MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展)机制,它允许邮件处理文本、图片、视频等多个不同类型的数据。例如,图片等二进制数据以ASCII码字符串编码的方式指明,就是利用MIME来描述标记数据类型。而在MIME扩展中会使用一种称为多部分对象集合(Multipart)的方法,来容纳多份不同类型的数据。
HTTP协议中也采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。通常是在图片或文本文件等上传时使用。在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-type,多部分对象集合包含的对象如下:
-
multipart/form-data:在Web表单文件上传时使用。
-
multipart/byteranges:状态码206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用
使用boundary字符串来划分多部分对象集合指明的各类实体。在boundary字符串指定的各个实体的起始行之前插入“--”标记(例如:--AaB03x、--THIS_STRING_SEPARATES),而在多部分对象集合对应的字符串的最后插入“--”标记(例如:--AaB03x--、--THIS_STRING_SEPARATES--)作为结束。多部分对象集合的每个部分类型中,都可以含有首部字段。另外,可以在某个部分中嵌套使用多部分对象集合。
3.7 范围请求
以前,下载一个尺寸稍大的图片或文件就已经很吃力。如果下载过程中遇到网络中断的情况,那就必须重头开始。为了解决上述问题,需要一种可恢复的机制。所谓恢复是指能从之前下载中断处恢复下载。要实现该功能需要指定下载的实体范围,指定范围发送的请求叫做范围请求(Range Request)。
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7b3fadf71f344f3c8348a0f08500b6bd~tplv-k3u1fbpfcp-watermark.webp)
执行范围请求时,会用到首部字段Range来指定资源的byte范围:
-
5001~10000字节
Range:bytes=5001-10000
-
从5001字节之后全部的
Range:bytes=5001-
-
从一开始到3000字节和5000~7000字节的多重范围
Range:bytes=-3000,5000-7000
针对范围请求,响应会返回状态码为206 Partial Content的响应报文。另外,对于多重范围的范围请求,响应会在首部字段Content-Type标明multipart/byteranges后返回响应报文。如果服务器端无法响应范围请求,则会返回状态码200 OK和完整的实体内容。
3.8 内容协商
同一个Web网站有可能存在着多份相同内容的页面。比如英语版和中文版的Web页面,它们内容上虽相同,但使用的语言却不同。当浏览器的默认语言为英语或中文,访问相同URI的Web页面时,则会显示对应的英语版或中文版的Web页面。这样的机制称为内容协商(ContentNegotiation)。
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7bb828b4ed764e6a8b09c8e9f7eb488c~tplv-k3u1fbpfcp-watermark.webp)
请求报文中的某些首部字段就是判断的基准(后面讲解):
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
内容协商技术有以下3种类型:
- 服务器驱动协商(Server-driven Negotiation):由服务器端进行内容协商。以请求的首部字段为参考,在服务器端自动处理。但对用户来说,以浏览器发送的信息作为判定的依据,并不一定能筛选出最优内容。
- 客户端驱动协商(Agent-driven Negotiation):由客户端进行内容协商的方式。用户从浏览器显示的可选项列表中手动选择。还可以利用JavaScript脚本在Web页面上自动进行上述选择。比如按OS的类型或浏览器类型,自行切换成PC版页面或手机版页面。
- 透明协商(Transparent Negotiation):是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。
四、HTTP状态码
4.1 什么是状态码
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6c2fc738038049c58877c417191842b8~tplv-k3u1fbpfcp-watermark.webp)
4.2 状态码类别
数字中的第一位指定了响应类别,后两位无分类。响应类别有以下5种。
仅记录在RFC2616上的HTTP状态码就达40种,若再加上WebDAV(Web-basedDistributed Authoring and Versioning,基于万维网的分布式创作和版本控制)(RFC4918、5842)和附加HTTP状态码(RFC6585)等扩展,数量就达60余种。别看种类繁多,实际上经常使用的大概只有14种。
4.3 2XX成功
2XX的响应结果表明请求被正常处理了。
-
200 OK
从客户端发来的请求在服务器端被正常处理了
-
204 NO CONTENT
服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,不允许返回任何实体的主体
-
206 Partial Content
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。
4.4 3XX重定向
3XX响应结果表明浏览器需要执行某些特殊的处理以正确处理请求
-
301 Moved Permanently
永久性重定向。URI已被分配到了新的URI。如果已经把资源对应的URI保存为书签了,这时应会按Location首部字段提示的URI重新保存。像下方给出的请求URI,当指定资源路径的最后忘记添加斜杠“/”,就会产生301状态码。
http://example.com/sample
-
302 Found
临时性重定向。URI已被分配了新的URI,希望用户(本次)能使用新的URI访问。与301不同的是,302状态码代表的资源不是被永久移动,只是临时性质的。已移动的资源对应的URI将来还有可能发生改变。比如,用户把URI保存成书签,但不会像301那样去更新书签。
-
303 See Other
由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。与302有着相同的功能,而303状态码明确表示客户端应当采用GET方法获取资源
当301、302、303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301、302标准是禁止将POST方法改变成GET方法的。
-
304 Not Modified
表示客户端发送附带条件的请求时,服务器端允许请求访问资源。但如果请求未满足条件,就会返回304 Not Modified。304虽然被划分在3XX类别中,但是和重定向没有关系。
-
307 Temporary Redirect
临时重定向。该状态码与302有着相同的含义。307会遵照浏览器标准,不会从POST变成GET。
4.5 4XX客户端错误
4XX的响应结果表明客户端是发生错误的原因所在
-
400 Bad Request
表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
-
401 Unauthorized
表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询(challenge)用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。另外若之前已进行过1次请求,则表示用户认证失败。
-
403 Forbidden
该状态码表明对请求资源的访问被服务器拒绝了。未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举的情况都可能是发生403的原因。
-
404 Not Found
该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
4.6 5XX服务器错误
-
500 Internal Server Error
该状态码表明服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障。
-
503 Service Unavailable
该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入Retry-After首部字段再返回给客户端。
状态码和状况可能不一致。不少返回的状态码响应都是错误的,但是用户可能察觉不到这点。比如Web应用程序内部发生错误,状态码依然返回200 OK,这种情况也经常遇到。
五、与HTTP协助的Web服务器
5.1 单台虚拟主机实现多个域名
HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。比如提供Web托管服务(Web Hosting Service)的供应商:
- 可以用一台服务器为多位客户服务
- 也可以以每位客户持有的域名运行各自不同的网站
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ea37b275cb564fdaa921d0b3f92a0be3~tplv-k3u1fbpfcp-watermark.webp)
在互联网上,域名通过DNS服务映射到IP地址之后访问目标网站,即当请求发送到服务器时,就以IP地址形式访问了。如果一台服务器内托管了多个域名,那么访问的将是相同的IP地址。在相同的IP地址下,就必须在发送HTTP请求时,在Host首部内完整指定主机名或域名的URI,这样才能进行区分。
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7953f480752848f4aa7cfddea555bc7e~tplv-k3u1fbpfcp-watermark.webp)
5.2 通信数据转发程序
HTTP通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理、网关和隧道。这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。
代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端:
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/36fc388d09eb43a8aaefe99a2974a4e4~tplv-k3u1fbpfcp-watermark.webp)
持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过代理服务器后再传给客户端。转发时,需要附加Via首部字段以标记出经过的主机信息:
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1f72b39c18d4e77beaf58a420a7d710~tplv-k3u1fbpfcp-watermark.webp)
作用:利用缓存技术(稍后讲解)减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的,等等。
代理可分为两种:
- 缓存代理:代理转发响应时, 缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。
- 透明代理:转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。
网关
网关是转发其他服务器通信数据的服务器。接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务:
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/72e4e44349e7457c8c473d16eb53d008~tplv-k3u1fbpfcp-watermark.webp)
作用:提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。
隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道本身不会去解析HTTP请求,即请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e675b98241d4aaaa55a32b86fcf9836~tplv-k3u1fbpfcp-watermark.webp)
作用:确保客户端能与服务器进行安全的通信。
5.3 缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,因此也就节省了通信流量和通信时间。缓存服务器是代理服务器的一种,即当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d30d1499eb434258ba729466cf5716db~tplv-k3u1fbpfcp-watermark.webp)
缓存具有有效期限,所以不能保证每次都会返回对同资源的请求。当遇上源服务器上的资源更新时,如果还是使用不变的缓存,那就会演变成返回更新前的“旧”资源了。缓存会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取“新”资源。
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cb0f453190e043ba8e1be6224539f89c~tplv-k3u1fbpfcp-watermark.webp)
客户端也能缓存。缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。以InternetExplorer程序为例,把客户端缓存称为临时网络文件(Temporary InternetFile)。浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。
另外,和缓存服务器相同的一点是,当判定缓存过期后,会向源服务器确认资源的有效性。若判断浏览器缓存失效,浏览器会再次请求新资源。
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f4a046ebc7c0417b825a7310e16540f7~tplv-k3u1fbpfcp-watermark.webp)
六、HTTP首部
6.1 首部字段
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6c552896d62c441c8ec7a5307f622251~tplv-k3u1fbpfcp-watermark.webp)
6.2 首部字段结构
- HTTP首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔:
首部字段吗:字段值
Content-Type:text/html
- 字段值可以有多个值:
Keep-Alive:timeout=15,max=100
6.3 首部字段类型
-
通用首部字段(General Header Fields)
-
请求首部字段(Request Header Fields)
-
响应首部字段(Response Header Fields)
-
实体首部字段(Entity Header Fields)
6.4 通用首部字段
请求报文和响应报文两方都会使用的首部
Cache-Control
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/14afa282ebac4bec9a15e88a5c93472c~tplv-k3u1fbpfcp-watermark.webp)
Cache-Control:private,max-age=0,no-cache
表示是否能缓存:
-
Cache-Control:public #表明其他用户可利用缓存
-
Cache-Control:private #缓存服务器会对特定用户提供资源缓存的服务
-
Cache-Control:no-cache #缓存服务器不能对资源进行缓存。客户端不会接收缓存过的响应。可以防止防止从缓存中返回过期的资源
-
Cache-Control:no-cache=Location #如果指定具体参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。
控制可缓存的对象:
-
Cache-Control:no-store #规定缓存不能在本地存储请求或响应的任一部分。
指定缓存期限和认证:
-
Cache-Control:s-maxage:604900(单位秒) #如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源 #适用于供多位用户使用的公共缓存服务器 #当使用s-maxage指令后,则直接忽略对Expires首部字段及max-age指令的处理
-
Cache-Control:max-age=604900 ##如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源 #适用于同一用户
应用HTTP/1.1版本的缓存服务器遇到同时存在Expires首部字段的情况时,会优先处理max-age指令,而忽略掉Expires首部字段。而HTTP/1.0版本的缓存服务器的情况却相反,max-age指令会被忽略掉。
-
Cache-Control:min-fresh=60 #min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源 #当指定min-fresh为60秒,在这60秒以内如果有超过有效期限的资源都无法作为响应返回了
-
Cache-Control:max-stale=3600 #如果指令未指定参数值,那么无论经过多久,客户端都会接收响应 #如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。
-
Cache-Control:only-if-cached #客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。 #缓存服务器不重新加载响应,也不会再次确认资源有效性。
-
Cache-Control:must-revalidate #代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。 #使用must-revalidate指令会忽略请求的max-stale指令 #若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条504(Gateway Timeout)状态码
-
Cache-Control:proxy-revalidate 3要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
-
Cache-Control:no-transform #无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。 #可防止缓存或代理压缩图片等类似操作
Connection
控制不再转发给代理的首部字段
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7492c95a0f7343938f6ae8172aa50d31~tplv-k3u1fbpfcp-watermark.webp)
Connection:不再转发的首部字段名
管理持久连接
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5b7fdf1f1e684935ae83160404eea08f~tplv-k3u1fbpfcp-watermark.webp)
HTTP/1.1版本的默认连接都是持久连接。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close:
Connection:close
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e389b30465c4beab7c653d5b684b3bd~tplv-k3u1fbpfcp-watermark.webp)
HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive:
Connection:Keep-Alive
Date
表明创建HTTP报文的日期和时间
Date:Tue,03 Jul 2012 04:40:59 GMT #HTTP/1.1协议使用在RFC1123中规定的格式
Date:Tue,03-Jul-12 04:40:59 GMT #之前的HTTP协议使用在RFC850中定义的格式
Date:Tue Jul 03 04:40:592012 #其他格式。与C标准库内的asctime()函数的输出格式一致
Pragma
Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。
Pragma:no-cache
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/624e68d00a054522af9d35705cb92945~tplv-k3u1fbpfcp-watermark.webp)
所有的中间服务器如果都能以HTTP/1.1为基准,那直接采用Cache-Control: no-cache指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的HTTP协议版本却是不现实的。因此,发送的请求会同时含有下面两个首部字段。
Cache-Control:no-cache
Pragma:no-cache
Trailer
事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在HTTP/1.1版本分块传输编码时。下面指定首部字段Trailer的值为Expires,在报文主体之后(分块长度0之后)出现了首部字段Expires。
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/88768baf8c904e8a8903a1463d8be28a~tplv-k3u1fbpfcp-watermark.webp)
Transfer-Encoding
规定了传输报文主体时采用的编码方式
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/748ebcd0cd1c4993b11959e491d42b39~tplv-k3u1fbpfcp-watermark.webp)
Upgrade
用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议
Connection的值被指定为Upgrade。Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。因此,使用首部字段Upgrade时,还需要额外指定Connection:Upgrade。
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e6a785ce7b984baf89db34e427dc4860~tplv-k3u1fbpfcp-watermark.webp)
Via
追踪客户端与服务器之间的请求和响应报文的传输路径。报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。还可避免请求回环的发生。所以必须在经过代理时附加该首部字段内容。
Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到由TRACE方法发送过来的请求(其中Max-Forwards: 0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7b834c554be74e038ead534ac3b23e1a~tplv-k3u1fbpfcp-watermark.webp)
Warning
告知用户一些与缓存相关的问题的警告
Warning:113 gw.hackr.jp:8080 "Heuristic expiration" Tue,03 Jul=>201205:09:44 GMT
#格式:
Warning:[警告码][警告的主机:端口号]“[警告内容]”([日期时间])
6.5 请求首部字段
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
Accept
通知服务器用户代理能够处理的媒体类型及媒体类型的相对优先级
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/
*;q=0.8
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3f758c4ffc7e4cf0b9f41b55ba3d326c~tplv-k3u1fbpfcp-watermark.webp)
- 文本文件:text/html, text/plain, text/css,application/xhtml+xml, application/xml ...
- 图片文件:image/jpeg, image/gif, image/png ...
- 视频文件:video/mpeg, video/quicktime ...
- 应用程序使用的二进制文件:application/octet-stream, application/zip ...
若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,用分号(;)进行分隔。权重值q的范围是0~1(可精确到小数点后3位),且1为最大值。不指定权重q值时,默认权重为q=1.0。当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。
Accept-Charset
通知服务器用户代理支持的字符集及字符集的相对优先顺序。
Accept-Charset:iso-8859-5,unicode-1-1;q=0.8
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/374ad35976d84abcb6971a62c9d5ffd1~tplv-k3u1fbpfcp-watermark.webp)
Accept-Encoding
告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
Accept-Encoding:gzip,deflate
- gzip:由文件压缩程序gzip(GNU zip)生成的编码格式(RFC1952),采用Lempel-Ziv算法(LZ77)及32位循环冗余校验(Cyclic RedundancyCheck,通称CRC)
- compress:由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch算法(LZW)
- deflate:组合使用zlib格式(RFC1950)及由deflate压缩算法(RFC1951)生成的编码格式
- identity:不执行压缩或不会变化的默认编码格式
可采用权重q值来表示相对优先级。另外,也可使用星号(*)作为通配符,指定任意的编码格式
Accept-Language
告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。
Accept-Language:zh-cn,zh;q=0.7,en-us,en;q=0.3
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1cc917e173dc45838a7356111e874870~tplv-k3u1fbpfcp-watermark.webp)
Authorization
告知服务器用户代理的认证信息(证书值)。发生在客户端与服务器之间
Authorization:Basic dWVub3Nlb jpwYXNzd29yZA==
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b9a5838f93c74d5fb42c48fc22c8f5c4~tplv-k3u1fbpfcp-watermark.webp)
Proxy-Authorization
接收到从代理服务器发来的认证质询时,客户端告知服务器认证所需要的信息。发生在客户端与代理之间
Expect
告知服务器期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码417 ExpectationFailed
Expect:100-continue
From
告知服务器使用用户代理的用户的电子邮件地址。
Form:info@hackr.jp
Host
告知服务器,请求的资源所处的互联网主机名和端口号。首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联。请求被发送至服务器时,请求中的主机名会用IP地址直接替换解决。但如果这时,相同的IP地址下部署运行着多个域名,就需要使用首部字段Host来明确指出请求的主机名。
Host:www.hackr.jp
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f126b1baffa44a448bfc78d176907838~tplv-k3u1fbpfcp-watermark.webp)
若服务器未设定主机名,那直接发送一个空值即可:
Host:
Range
对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码为206Partial Content的响应。无法处理该范围请求时,则会返回状态码200 OK的响应及全部资源。
Range:bytes=5001-10000
形如If-xxx这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2ae0ab7649af455ea0760f5c137aed66~tplv-k3u1fbpfcp-watermark.webp)
If-Match
告知服务器匹配资源所用的实体标记(ETag)值,这时的服务器无法使用弱ETag值。仅当两者一致时,才会执行请求。反之,则返回状态码412 Precondition Failed的响应。还可以使用星号(*)指定If-Match的字段值,这时服务器将会忽略ETag的值,只要资源存在就处理请求。
If-Match:"123456"
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/099338eaf8f643bea839d59838e31188~tplv-k3u1fbpfcp-watermark.webp)
If-Range
告知服务器,当指定的If-Range字段值(ETag值或者时间)和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。(是If-Match和Range的组合的改进版)
If-Modified-Since
告知服务器,如果资源更新时间晚于If-Modified-Since字段值,处理该请求;相反,如果资源更新时间先于If-Modified-Since字段值,而请求的资源都没有过更新,则返回状态码304Not Modified的响应。
If-Modified-Since:Thu,15 Apr 2004 00:00:00 GMT
If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段Last-Modified来确定
If-Unmodified-Since
与If-Modified-Since的作用相反。告知服务器,如果请求的资源在字段值之后未发生更新,才处理请求。如果在指定日期时间后发生了更新,则以状态码412 Precondition Failed作为响应返回
Max-Forwards
通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,指定可经过的服务器最大数目。当服务器接收到Max-Forwards值为0的请求时,则不再进行转发,而是直接返回响应。
Max-Forwards:10
使用HTTP协议通信时,请求可能会经过代理等多台服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器返回的响应了。对此,我们无从可知。而Max-Forwards可以针对以上问题产生的原因展开调查
Referer
告知服务器请求的原始资源的URI。客户端一般都会发送Referer首部字段给服务器。如果直接在浏览器的地址栏输入URI,或出于安全性的考虑,可以不发送该首部字段。因为原始资源的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则有可能导致保密信息的泄露。
TE
告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段Accept-Encoding的功能很相像,但是用于传输编码。
TE:gzip,deflate;q=0.5
还可以指定伴随trailer字段的分块传输编码的方式:
TE:trailers
User-Agent
创建请求的浏览器和用户代理名称等信息传达给服务器。
6.6 响应首部字段
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
Accept-Ranges
告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。可指定的字段值有两种,可处理范围请求时指定其为bytes,反之则指定其为none
Accept-Ranges:bytes
Age
告知客户端源服务器在多久前创建了响应。字段值的单位为秒。
Age:600
若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。
ETag
告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag值
ETag:"82e22293907ce725faf67773957acd12"
另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。
资源被缓存时,就会被分配唯一性标识。例如,当使用中文版的浏览器访问http://www.google.com/时,就会返回中文版对应的资源,而使用英文版的浏览器访问时,则会返回英文版对应的资源。两者的URI是相同的,所以仅凭URI指定缓存的资源是相当困难的。若在下载过程中出现连接中断、再连接的情况,都会依照ETag值来指定资源。
强ETag值和弱Tag值
强ETag值:不论实体发生多么细微的变化都会改变其值
ETag:"usagi-1234"
弱ETag值:只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/
ETag:W/"usagi-1234"
Location
使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。基本上,该字段会配合3xx:Redirection的响应,提供重定向的URI。几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。
Location:http://www.usagidesign.jp/sample.html
WWW-Authenticate
用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic或是Digest)和带参数提示的质询(challenge)。状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate。(客户端与服务器之间)
WWW-Authenticate:Basic realm="Usagidesign Auth"
Proxy-Authenticate
把由代理服务器所要求的认证信息发送给客户端。(客户端与代理之间)
Proxy-Authenticate:Basic realm="Usagidesign Auth"
Retry-After
告知客户端应该在多久之后再次发送请求。主要配合状态码503 Service Unavailable响应,或3xx Redirect响应一起使用。
Retry-After:120
Server
首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息。还有可能包括版本号和安装时启用的可选项。
Server:Apache/2.2.17 (Unix)
Server:Apache/2.2.6 (Unix) PHP/5.2.5
Vary
对缓存进行控制。从代理服务器接收到源服务器返回包含Vary指定项的响应之后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。
Vary:Accept-Language
6.7 实体首部字段
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d08dbcb86ea940ccb6f6dd296fc0e137~tplv-k3u1fbpfcp-watermark.webp)
Allow
通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。
Content-Encoding
告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。(主要采用:gzip、compress、deflate、identity)
Content-Language
告知客户端,实体主体使用的自然语言
Content-Length
告知实体主体部分的大小(单位是字节)。(对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。)
Content-Location
给出与报文主体部分相对应的URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。
比如,对于使用首部字段Accept-Language的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI。(访问http://www.hackr.jp/返回的对象却是http://www.hackr.jp/index-ja.html等类似情况)
Content-MD5
Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
对报文主体执行MD5算法获得的128位二进制数,再通过Base64编码后将结果写入Content-MD5字段值。由于HTTP首部无法记录二进制值,所以要通过Base64编码处理。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的MD5算法。计算出的值与字段值作比较后,即可判断出报文主体的准确性。
采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。其中一个原因在于,内容如果能够被篡改,那么同时意味着Content-MD5也可重新计算然后被篡改。所以处在接收阶段的客户端是无法意识到报文主体以及首部字段Content-MD5是已经被篡改过的。
Content-Range
针对范围请求,返回响应时使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。
Content-Type
说明了实体主体内对象的媒体类型。
Content-Type:text/html;charset=UTF-8
Expires
将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。
Expires:Wed,04 Jul 2012 08:26:05 GMT
源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。但是,当首部字段Cache-Control有指定max-age指令时,比起首部字段Expires,会优先处理max-age指令。
Last-Modified
指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。
Last-Modified:Wed,23 May 2012 09:59:55 GMT
6.8 非HTTP/1.1首部字段
在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。还有Cookie、Set-Cookie和Content-Disposition等在其他RFC中定义的首部字段,它们的使用频率也很高。
6.9 端到端首部和逐跳首部首部字段
-
端到端首部(End-to-end Header):分在此类别中的首部会转发给请求/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
-
逐跳首部(Hop-by-hop Header):分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后版本中,如果要使用hop-by-hop首部,需提供Connection首部字段。
-
Connection
-
Keep-Alive
-
Proxy-Authenticate
-
Proxy-Authorization
-
Trailer
-
TE
-
Transfer-Encoding
-
Upgrade
除这些之外,其他字段都属于端到端首部
-
6.10 为Cookie服务的首部字段
Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前存放的Cookie。
调用Cookie时,由于可校验Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie内的数据不会因来自其他Web站点和攻击者的攻击而泄露。
Set-Cookie
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
Set-Cookie:status=enable; expires=Tue,05 Jul 2011 07:26:31 GM T;=〉
path=/; domain=.hackr.jp;
-
expires:指定浏览器可发送Cookie的有效期。当省略expires属性时,其有效期仅限于维持浏览器会话(Session)时间段内。这通常限于浏览器应用程序被关闭之前。另外,一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显式删除Cookie的方法。但可通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。
-
path:限制指定Cookie的发送范围的文件目录
-
domain:指定的域名可做到与结尾匹配一致。比如,当指定example.com后,除example.com以外,www.example.com或www2.example.com等都可以发送Cookie。因此,除了针对具体指定的多个域名发送Cookie之外,不指定domain属性显得更安全。
-
secure:用于限制Web页面仅在HTTPS安全连接时,才可以发送Cookie
Set-Cookie:name=value;secure
以上例子仅当在https://www.example.com/安全连接的情况下才会进行Cookie的回收。也就是说,即使域名相同,http://www.example.com/(HTTP)也不会发生Cookie回收行为。当省略secure属性时,不论HTTP还是HTTPS,都会对Cookie进行回收。
-
HttpOnly:使JavaScript脚本无法获得Cookie。其主要目的为防止跨站脚本攻击(Cross-site scripting,XSS)对Cookie的信息窃取
Set-Cookie:name=value;HttpOnly
通常从Web页面内还可以对Cookie进行读取操作。但使用JavaScript的document.cookie就无法读取附加HttpOnly属性后的Cookie的内容了。因此,也就无法在XSS中利用JavaScript劫持Cookie了。
Cookie
告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。
Cookie:status=enable
6.11 其他首部字段
HTTP首部字段是可以自行扩展的。所以在Web服务器和浏览器的应用上,会出现各种非标准的首部字段。
X-Frame-Options
属于HTTP响应首部,用于控制网站内容在其他Web网站的Frame标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。
X-Frame-Options:DENY
首部字段X-Frame-Options可指定的字段值如下:
- DENY:拒绝
- SAMEORIGIN:仅同源域名下的页面(Top-level-browsing-context)匹配时许可。(比如,当指定http://hackr.jp/sample.html页面为SAMEORIGIN时,那么hackr.jp上所有页面的frame都被允许可加载该页面,而example.com等其他域名的页面就不行了)
支持该首部字段的浏览器有:Internet Explorer 8、Firefox 3.6.9+、Chrome4.1.249.1042+、Safari 4+和Opera 10.50+ 等。
X-XSS-Protection
属于HTTP响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器XSS防护机制的开关。
X-XSS-Protection:1
首部字段X-XSS-Protection可指定的字段值如下:
- 0 :将XSS过滤设置成无效状态
- 1 :将XSS过滤设置成有效状态
DNT
属于HTTP请求首部,其中DNT是Do Not Track的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
首部字段DNT可指定的字段值如下:
- 0 :同意被追踪
- 1 :拒绝被追踪
P3P
属于HTTP响应首部,通过利用P3P(The Platform for PrivacyPreferences,在线隐私偏好平台)技术,可以让Web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
P3P:CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa=>
IVAa IVDa OUR BUS IND UNI COM NAV INT"
要进行P3P的设定,需按以下操作步骤进行:
- 步骤1: 创建P3P隐私
- 步骤2: 创建P3P隐私对照文件后,保存命名在/w3c/p3p.xml
- 步骤3: 从P3P隐私中新建Compact policies后,输出到HTTP响应中
协议中对X-前缀的废除在HTTP等多种协议中,通过给非标准参数加上前缀X-,来区别于标准参数,并使那些非标准的参数作为扩展变成可能。但是这种简单粗暴的做法有百害而无一益,因此在“RFC 6648- Deprecating the "X-" Prefix and SimilarConstructs in Application Protocols”中提议停止该做法。然而,对已经在使用中的X-前缀来说,不应该要求其变更。