图解HTTP [上官宣] Summary after reading


第 1 章 了解Web及网络基础

术语

现已提出的3项WWW构建技术:

①把SGML(标准通用标记语言)作为页面的文本标记语言的HTML(超文本标记语言)

②作为文档传递协议的HTTP(超文本传输协议)

③指定文档所在地址的URL(统一资源定位符)

TCP/IP协议族:是互联网相关的各类协议族的总称,HTTP协议也是其中一员

FTP:文件传输协议

DNS:域名系统

DNS服务:从域名查找IP地址,或者反从IP地址查找域名

TCP:传输控制协议

UDP:用户数据报协议

NIC:网络适配器,即网卡

MAC地址:MAC地址用于在网络中唯一标识一个网卡。

IP地址:指明了节点被分配到的地址

LAN:局域网

ARP:ARP是一种用以解析地址的协议,根据通信方的IP地址就可以反查出对方的MAC地址

可靠的字节流服务:字节流服务指的是为了方便传输而将大块数据分割成以报文段为单位的数据包进行管理,可靠的指的是把数据准确可靠的传给对方

URL:统一资源定位符

URI:统一资源标识符,就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。标准的URI协议方案有30种左右

RFC:制定HTTP协议技术标准的文档


  • HTTP版本:HTTP/0.9、HTTP/1.0、HTTP/2.0。
  • TCP/IP协议族按层次分别分为以下4层:应用层、传输层、网络层、数据链路层。
  • 应用层:应用层决定了向用户提供应用服务时通信的活动。比如:FTP、DNS服务、HTTP协议等。
  • 传输层:传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。在传输层有两个性质不同的协议:TCP、UDP。
  • 网络层:网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径到达对方计算机(在众多的选项中选择一条传输路线),并把数据包发送给对方。比如:IP协议等。
  • 链路层:用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC、光纤等物理可见部分,且包括连接器等一切传输媒体。
  • 作为发送端的客户端在应用层(HTTP协议)发出一个HTTP请求。接着,为了方便传输,在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。在网络层(IP协议),增加作为通信的MAC地址后转发给链路层。这样一来,发往网络的通信请求就准备齐全了。当传送到服务器的应用层,则服务器才真正的接受到请求。

  • 发送端在层与层传输数据时,经过每一层必定会被打上一个该层所属的首部信息,反之,接受层在层与层传输数据时,每经过一层时会把对应的首部信息去掉。
  • 这种把数据包装起来的做法称为封装。
  • IP地址可以和MAC地址进行配对。IP地址可变换,MAC地址基本上不会更改。
  • IP协议:几乎所有的使用网络的系统都会用到IP协议。IP协议的作用就是把各种数据包传送给对方,其中传送到目的地需要满足的两个最重的条件是IP地址和MAC地址。在经过中转设备时,会利用下一站中转设备的MAC地址来搜索下一个中转目标,这时会采用ARP协议。
  • TCP协议:可以提供可靠的字节流服务。TCP协议为了容易传送大数据而把数据分割,而且TCP协议能够确认数据最终是否送达对方(三次握手策略)。
  • 三次握手策略:用TCP协议把数据包发送出去后,TCP会向对方确认是否成功送达。握手中使用了TCP的标志——SYN(synchronize)和ACK(acknowledgement)。发送端首先发送一个带有SYN标志的数据包给对方。接收端收到后,回传一个带SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表握手结束。若握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
  • URI用字符串标识某一互联网资源,而URL标识资源的地点(互联网上所处的位置)。可见URL是URI的子集。
  • 表示指定的URI,要使用涵盖全部必要信息的绝对URI、绝对URL以及相对URL。
  • 相对URL是指从浏览器中基本URI处指定的URL,形如:/image/logo.gif。

  • 上图为绝对URI格式。地址可以是类似hackr.jp这种DNS可解析的名称,或是192.168.1.1这类IPv4 地址名,还可以是[0:0:0:0:0:0:0:1]这样用方括号括起来的IPv6地址名。

第 2 章 简单的HTTP协议

CGI:通用网关接口

XST:跨站追踪


  • HTTP协议能够明确分辨哪边是客户端,哪边是服务器端。HTTP协议规定,一定是先从客户端开始建立通信,服务器端在没有接受到请求之前不会发送响应。

  • 请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成的。

  • 响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。
  • 可选的响应首部字段和实体主题体之间存在一行空格。
  • HTTP是不保存状态的协议,即无状态协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。HTTP/1.1虽然是无状态协议,但为了实现期望的保存状态功能,于是引用了Cookie技术。有了Cookie技术再用HTTP协议通信,就可以管理状态了。

  • 当客户端请求访问资源而发送请求时,URI需要将作为请求报文中的请求URI包含在内。指定请求URI的方式有很多,如上图。除此之外,如果不是访问特定资源而是对服务器本身发起请求,可以用一个*代替请求URI。下面的例子是查询HTTP服务器端支持的HTTP方法种类。
1
OPTIONS * HTTP/1.1
HTTP方法 作用 缺陷 响应
GET:获取资源 用来请求访问已被URI识别的资源。 如果是文本,则保持原样返回;如果像是CGI那样的程序,则返回执行后的输出结果。
POST:传输实体主体 用来传输实体的主体。 返回服务器接收数据的处理结果。
PUT:传输文件 就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。 HTTP/1.1的PUT方法自身不带验证机制,存在安全性问题,因此一般不使用该方法。 返回状态码204 No Content。
HEAD:获得报文首部 HEAD方法和GET方法一样,只是不返回报文主体的部分。用于确认URI的有效性及资源更新的日期时间等。 返回响应首部。
DELETE:删除文件 按请求URI删除指定的资源。 HTTP/1.1的DELETE方法自身不带验证机制,存在安全性问题,因此一般不使用该方法。 返回状态码204 No Content。
OPTIONS:询问支持的方法 查询针对请求URI指定的资源支持的方法 返回服务器支持的方法。
TRACE:追踪路径 是让Web服务器端将之前的请求通信返回给客户端的方法。发送请求时,在Max-Forwards首部字段填入数值,每经过一个服务器端就将该数字减1,当数字刚好减到0时,就停止继续传输,最后接收到请求的服务器端则返回状态码200 0K的响应。客户端通过TRACE方法可以查询发送出去的请求是怎样被加工修改/篡改的。 TRACE方法本身不常用,加上它容易引发XST攻击,就更不常用了。 最后接收到请求的服务器端则返回状态码200 0K的响应。
CONNECT:要求用隧道协议连接代理 要求在与代理服务器通信时建立隧道,是先用隧道协议进行TCP通信。主要用SSL和TSL协议把通信内容加密后经网络隧道传输。 返回状态码,若为HTTP/1.1 200 OK之后进入网络隧道。
  • CONNECT方法的格式如下。
1
CONNECT 代理服务器名:端口号 HTTP版本
  • 方法名区分大小写,注意使用大写字母。

  • HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。HTTP/1.1和一部分HTTP/1.0通过使用持久连接(keep-alive)的方法解决传输大量传输频繁连接的缺陷。持久连接的特点:只要任意一端没有明确提出断开连接,则保持TCP连接状态。在HTTP/1.1中,所有的连接默认都是持久连接。
  • 持久连接使得多数请求管线化方式发送成为可能。从前发送请求后需等待并受到响应才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就可以做到同时并发多个请求。
  • Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。Cookie会根据从服务器端发送的响应报文内一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下一次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现客户端发送过来的Cookie后,会对比服务器上的记录,对比后得到此客户端之前的状态信息。

第 3 章 HTTP报文内的HTTP信息

CR+LF:CR为回车符,16进制0x0d;LF为换行符,16进制0x0a

gzip:由文件压缩程序gzip(GNU zip)生成的编码格式,采用Lempel-Ziv算法(LZ77)及 2位循环冗余校验(Cyclic Redundancy Check,通称 CRC)

compress:由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch算法(LZW)

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

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


  • HTTP报文大致可以分为报文首部和报文主体两块,两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主题。
  • 请求报文和响应报文的结构如下。

  • 报文:HTTP通信中的基本单位。

  • 实体:作为请求或响应的有效荷载数据被传输,其内容由实体首部和实体主体组成。

  • HTTP报文的主体用于传输请求或响应的实体主体。通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生变化,才会导致它和报文主体产生差异。

  • 文件传输的内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。常见的内容编码:

    • gzip(GUN zip)
    • compress(UNIX系统的标准压缩)
    • deflate(zlib)
    • identity(不进行编码)
  • 在HTTP通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。这种把实体主体分块的功能称为分块传输编码。分块传输编码会将实体主体分成多个部分,每一块都会用十六进制来标记块的大小,而实体主体的最后一块会用”0(CR+LF)”来标记。

  • HTTP/1.1中存在一种称为传输编码的机制,它可以在通信时按某种编码方式传输,但只定义作用于分块传输编码中。

  • HTTP协议中采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。通常是在图片或文本文件等上传时使用。多部分对象集合包含的对象如下:

    • multipart/from-data:在Web表单文件上传时使用。

    • multipart/byteranges:状态码206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。

    在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-type。使用boundary字符串来划分多部分对象集合指明的各类实体。在boundary字符串指定的各个实体的起始行之前插入”- -“标记(例如:- -AaB03x、- -THIS_STRING_SEPARATES),而在多部分对象集合对应的字符串的最后插入”- -“标记(例如:- -AaB03x- -、- -THIS_STRING_SEPARATES- -)作为结束。 多部分对象集合的每个部分类型中,都可以含有首部字段。另外,可以在某个部分中嵌套使用多部分对象集合。

  • 指定范围发送的请求叫做范围请求。执行范围请求时,会用到首部字段Range来指定资源的byte范围,byte范围的指定形式如下。

1
2
3
4
5
6
7
8
5001-10000字节
Range:bytes=5001-10000

5001字节之后的全部字节
Range:bytes=5001-

0-3000字节和5000-7000字节的多重范围
Range:bytes=0-3000, 5000-7000
  • 针对范围请求,响应会返回状态码为206 Partial Content的响应报文。另外,对于多重范围的范围请求,响应会在首部字段Content-Type 标明multipart/byteranges后返回响应报文。 如果服务器端无法响应范围请求,则会返回状态码200 OK和完整的实体内容。

  • 内容协商机制是客户端和服务器端就相应的资源内容进行交涉,然后提供给客户端最为合适的资源。内容协商会以语言、字符集、编码方式等作为基准判断响应的资源。包含在请求报文中的某些首部字段就是判断的基准,如下:

    • Accept
    • Accept-Charset
    • Accept-Encoding
    • Accept-Language
    • Content-Language
  • 内容协商技术有三种类型:

    • 服务器驱动协商
    • 客户端驱动协商:用户根据浏览器显示的可选项列表手动选择,或利用Javascript脚本在Web页面上自动进行选择等。
    • 透明协商:上两者的结合体,用户端和服务器端结合各自进行内容协商。

第 4 章 返回结果的HTTP状态码

类别 原因短语
1XX Informational(信息性状态码) 接受的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错
  • 2XX成功
    • 200 OK:表示从客户端发来的请求在服务器端被正常处理了。
    • 204 No Content:该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如, 当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新。一般在只需要从客户端往服务器发送信息,而对服务器端不需要发送新信息内容的情况下使用。
    • 206 Partial Content:该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。
  • 3XX重定向
    • 301 Moved Permanently:永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。也就是说,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。
    • 302 Found:临时性重定向。该状态码表示请求的资源已经被分配了新的URI,希望用户本次能使用新的URI访问。和301 Moved Permanently状态码相似,但302状态码代表的资源不 是被永久移动,只是临时性质的。
    • 303 See Other:该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。303状态码和302 Found状态码有着相同的功能,但303状态码明确表示客户端应当采用GET方法获取资源,这点与302状态码有区别。
    • 304 Not Modified:该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。附带条件的请求是指采用GET方法的请求报文中包含 If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部。
    • 307 Temporary Redirect:临时重定向。该状态码与302 Found有着相同的含义。尽管302标准禁止POST变换成GET,但实际使用时大家并不遵守。307会遵照浏览器标准,不会从POST变成GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。
  • 4XX客户端错误
  • 400 Bad Request:该状态码表示请求报文中存在语法错误。
  • 401 Unauthorized:该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。另外若之前已进行过1次请求,则表示用户认证失败。 返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。
  • 403 Forbidden:该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。
  • 404 Not Found:该状态码表明服务器上无法找到请求的资源。
  • 5XX服务器错误
  • 500 Internal Server Error:该状态码表明服务器端在执行请求时发生了错误。
  • 503 Service Unavailable:该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法 处理请求。如果事先得知解除以上状况需要的时间,最好写入RetryAfter首部字段再返回给客户端。

当301、302、303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。 301、302标准是禁止将POST方法改变成GET方法的,但实际使用时大家都会这么做。

第 5 章 与HTTP协作的Web服务器

FTP:传输文件时使用的协议。该协议历史久远,可追溯到1973年前后,比TCP/IP协议族的出现还要早。虽然它在1995年被HTTP的 流量超越,但时至今日,仍被广泛沿用


  • HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。这是因为利用了虚拟主机(Virtual Host,又称虚拟服务器)的功能。 即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器。
  • 在互联网上,域名通过DNS服务映射到IP地址(域名解析)之后访问目标网站。可见,当请求发送到服务器时,已经是以IP地址形式访问了。
  • 在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。
  • 持有资源实体的服务器被称为源服务器。
  • 代理:代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。每次通过代理服务器转发请求或响应时,需要追加写入Via首部信息来表明经过的主机信息。使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的等等。代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。
    • 缓存代理:代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。 当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。
    • 透明代理:转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。
  • 网关:网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务。 利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时, 网关可以和信用卡结算系统联动。
  • 隧道:隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。 隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。
  • 缓存服务器是代理服务器的一种,并归类在缓存代理类型中。
  • 即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取”新”资源。
  • 缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。以Internet Explorer程序为例,把客户端缓存称为临时网络文件(Temporary Internet File)。另外,和缓存服务器相同的一点是,当判定缓存过期后,会向源服务器确认资源的有效性。若判断浏览器缓存失效,浏览器会再次请求新资源。

第 6 章 HTTP首部

ETag:实体标记,是与特定资源关联的确定值。资源更新后ETag也会随之更新,ETag中有强ETag值和弱ETag值之分

强ETag值:不论实体发生多么细微的变化都会改变其值,ETag: "usagi-1234"

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

100 Continue: 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分

101 Switching Protocols:指示服务器正在根据发送包括Upgrade请求头的消息的客户端的请求切换到的协议

304 Not Modified:当客户端有一个缓存的文档,通过提供一个If-Modified-Since头信息可指出客户端只希望文档在指定日期之后有所修改时才会重载此文档,用这种方式可以进行有条件的请求。304是指缓冲的版本已经被更新并且客户端应刷新文档

412 Precondition Failed:先决条件失败

417 Expectation Failed:如果服务器得到一个带有100-continue值的Expect请求头信息,这是指客户端正在询问是否可以在后面的请求中发送附件。在这种情况下,服务器也会用该状态(417)告诉浏览器服务器不接收该附件或用100(SC_CONTINUE)状态告诉客户端可以继续发送附件,该状态是新加入HTTP/1.1的

504 Gateway Timeout:网页请求超时


  • HTTP首部字段语法如下。
1
2
3
4
首部字段名:字段值

字段值对应单个HTTP首部字段可以有多个值:
Keep-Alive:timeout=15, max=100
  • 当HTTP报文首部中出现了两个或两个以上具有相同首部字段名时会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。
  • 4种HTTP首部字段类型:
    • 通用首部字段(General Header Fields):请求报文和响应报文两方都会使用的首部。
    • 请求首部字段(Request Header Fields):补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
    • 响应首部字段(Response Header Fields):补充了响应的附加内容,也会要求客户端附加额外的内容信息。
    • 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
  • HTTP首部字段将定义成缓存代理和非缓存代理的行为分为两种类型:
    • 端到端首部(End-to-end Header):分在此类别中的首部会转发给请求/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
    • 逐跳首部(Hop-by-hop Header):分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后的版本中,如果要是用hop-by-hop首部,需提供Connection首部字段。除了下面8个首部字段外,其他所有字段都属于端到端首部。
      • Connection:通用首部字段,逐跳首部、连接的管理。
      • Keep-Alive:响应首部字段,如要持续连接,则需要指定Connection首部字段的值为Keep-Alive。 客户端发送请求给服务器时,服务器端会加上首部字段Keep-Alive及首部字段Connection后返回响应。
      • Proxy-Authenticate:响应首部字段,代理服务器对客户端的认证信息。
      • Proxy-Authorization:请求首部字段,代理服务器要求客户端的认证信息。
      • Trailer:通用首部字段,报文末端的首部一览。
      • TE:请求首部字段,传输编码的优先级。
      • Transfer-Encoding:通用首部字段,指定报文主体的传输编码方式。
      • Upgrade:通用首部字段,升级为其他协议。

1. 通用首部字段

首部字段名 说明
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知

1.1 Cache-Control

  • 通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
  • 可用的指令按请求和响应分类。
缓存请求指令
指令 参数 说明
no-cache 强制向源服务器再次验证
no-store 不缓存请求或响应的任何内容
max-age=[秒] 必须 响应最大Age值
max-statle=[秒] 可省略 接收已过期响应
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指令后,响应只以特定的用户作为对象,这与public指令的行为相反。 缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。
  • no-cache指令:使用no-cache指令的目的是为了防止从缓存中返回过期的资源。
    • Cache-Control: no-cache,使用no-cache指令的目的是为了防止从缓存中返回过期的资源。 客户端发送的请求中如果包含no-cache指令,则表示客户端将不会接收缓存过的响应。于是,”中间”的缓存服务器必须把客户端请求转发给源服务器。 如果服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行强缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。
    • Cache-Control: no-cache=Location,由服务器返回的响应中,若报文首部字段Cache-Control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。
控制可执行缓存的对象的指令
  • no-store:Cache-Control: no-store,当使用no-store指令时,暗示请求(和对应的响应)或响应中包含机密信息。因此,该指令规定缓存不能在本地存储请求或响应的任一部分。
  • 从字面意思上很容易把no-cache误解成为不缓存,但事实上no-cache代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,也许称为do-not-serve-from-cache-without-revalidation更合适。no-store才是真正地不进行缓存。
指定缓存期限和认证的指令
  • max-age指令:Cache-Control: max-age=604800(单位 :秒),当客户端发送的请求中包含max-age指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。 另外,当指定max-age值为0,那么缓存服务器通常需要将请求转发给源服务器。当服务器返回的响应中包含max-age指令时,在max-age时间内,缓存服务器将不对资源的有效性再作确认,而max-age数值代表资源保存为缓存的最长时间。应用HTTP/1.1版本的缓存服务器遇到同时存在Expires首部字段的情况时,会优先处理max-age指令,而忽略掉Expires首部字段。而HTTP/1.0版本的缓存服务器的情况却相反,max-age指令会被忽略掉。

  • s-maxage指令:Cache-Control: s-maxage=604800(单位 :秒),s-maxage指令的功能和 max-age指令的相同,它们的不同点是s-maxage指令只适用于供多位用户使用的公共缓存服务器 (一般指代理)。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。另外,当使用s-maxage指令后,则直接忽略对Expires首部字段及max-age指令的处理。

  • min-fresh指令:Cache-Control: min-fresh=60(单位 :秒),min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源。 比如,当指定min-fresh为60秒后,过了60秒的资源都无法作为响应返回了。

  • max-stale指令:Cache-Control: max-stale=3600(单位 :秒),使用max-stale可指示缓存资源,即使过期也照常接收。如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。

  • only-if-cached指令:Cache-Control: only-if-cached,使用only-if-cached指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码504 Gateway Timeout。

  • must-revalidate指令:Cache-Control: must-revalidate,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条 504(Gateway Timeout)状态码。 另外,使用must-revalidate指令会忽略请求的max-stale指令(即使已经在首部使用了max-stale,也不会再有效果)。

  • proxy-revalidate指令:Cache-Control: proxy-revalidate,要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。

  • no-transform指令:Cache-Control: no-transform,规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。 这样做可防止缓存或代理压缩图片等类似操作。

Cache-Control扩展
  • cache-extension token:Cache-Control: private, community="UCI",通过cache-extension标记(token),可以扩展Cache-Control首部字段内的指令。 如上例,Cache-Control首部字段本身没有community这个指令。借助extension tokens实现了该指令的添加。如果缓存服务器不能理解community这个新指令,就会直接忽略。因此,extension tokens仅对能理解它的缓存服务器来说是有意义的。

1.2 Connection

  • 作用:
    • 控制不再转发给代理的首部字段。
    • 管理持久连接。
  • Connection: 不再转发的首部字段名,在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段(即Hop-by-hop首部)。
  • 管理持久连接:
    • Connection: close,关闭可持久化连接。HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close。
    • Connection: Keep-Alive,HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。 客户端发送请求给服务器时,服务器端会加上首部字段Keep-Alive及首部字段Connection后返回响应。

1.3 Date

  • 首部字段Date表明创建HTTP报文的日期和时间。
  • HTTP/1.1协议使用在RFC1123中规定的日期时间的格式,如:Date: Tue, 03 Jul 2012 04:40:59 GMT,之前的HTTP协议版本中使用在RFC850中定义的格式,如:Date: Tue, 03-Jul-12 04:40:59 GMT,除此之外还有:Date: Tue Jul 03 04:40:59 2012

1.4 Pragma

  • Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义,规范定义的形式唯一。
  • Pragma: no-cache,该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。有的中间服务器如果都能以HTTP/1.1为基准,那直接采用Cache-Control: no-cache指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的HTTP协议版本却是不现实的。因此,发送的请求会同时含有两个首部字段。Cache-Control: no-cachePragma: no-cache

1.5 Trailer

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

1.6 Transfer-Encoding

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

1.7 Upgrade

  • 首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
  • 例:首部字段Upgrade指定的值为TLS/1.0。Connection的值被指定为Upgrade。Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。因此,使用首部字段Upgrade时,还需要额外指定 Connection:Upgrade。 对于附有首部字段Upgrade的请求,服务器可用101 Switching Protocols态码作为响应返回。

1.8 Via

  • 使用首部字段Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径,然后再进行转发。
  • 报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。首部字段Via不仅用于追踪报文的转发,还可避免请求回环的发生。 所以必须在经过代理时附加该首部字段内容。
  • 服务器在Via首部附加服务器信息,也可增加1个新的Via首部写入服 务器信息。
  • Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到由TRACE方法发送过来的请求(其中 Max-Forwards: 0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。

1.9 Warning

  • HTTP/1.1的Warning首部是从HTTP/1.0的响应首部(Retry-After)演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。
  • Warning: [警告码][警告的主机:端口号]"[警告内容]"([日期时间]),最后的日期时间部分可省略。如:Warning: 113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03
  • HTTP/1.1中定义的警告码如下。
警告码 警告内容 说明
110 Response is stale(响应已过期) 代理返回已过期的资源
111 Revalidation failed(再验证失败) 代理再验证资源有效性时失败(服务器无法到达等原因)
112 Disconnection operation(断开连接操作) 代理与互联网连接被故意切断
113 Heuristic expiration(试探性过期) 响应的使用期超过24小时(有效缓存的设定时间大于24小时的情况下)
199 Miscellaneous warning(杂项警告) 任意的警告内容
214 Transformation applied(使用了转换) 代理对内容编码或媒体类型等执行了某些处理时
299 Miscellaneous persistent warning(持久杂项警告) 任意的警告内容

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 对请求中RUI的原始获取方
TE 传输编码的优先级
User-Agent HTTP客户端程序的信息

2.1 Accept

  • Accept: text/html,application/xhtml+xml,application/xml;q=0.9,Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型。
  • 媒体类型的例子:
    • 文本文件:
      • 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。当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。

2.2 Accept-Charset

  • Accept-Charset: iso-8859-5, unicode-1-1;q=0.8,Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段Accept相同的是可用权重q值来表示相对优先级。 该首部字段应用于内容协商机制的服务器驱动协商。

2.3 Accept-Encoding

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

  • 内容编码:

    • gzip(GUN zip)
    • compress(UNIX系统的标准压缩)
    • deflate(zlib)
    • identity(不进行编码)
  • 采用权重q值来表示相对优先级,这点与首部字段Accept相同。另外,也可使用星号(*)作为通配符,指定任意的编码格式。

2.4 Accept-Language

  • Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3,首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集,以及自然语言集的相对优先级。可一次指定多种自然语言集。

2.5 Authorization

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

2.6 Expect

  • Expect: 100-continue,客户端使用首部字段Expect来告知服务器,期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码417 Expectation Failed。 客户端可以利用该首部字段,写明所期望的扩展。虽然HTTP/1.1规范只定义了100-continue(状态码100 Continue之意)。 等待状态码100响应的客户端在发生请求时,需要指定Expect:100- continue。

2.7 From

  • 首部字段From用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能包含From首部字段(但可能会因代理不同,将电子邮件地址记录在User-Agent首部字段内)。

2.8 Host

  • Host: www.hackr.jp,首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。虚拟主机运行在同一个IP上,因此使用首部字段Host加以区分。
  • Host: www.hackr.jp,若服务器未设定主机名,那直接发送一个空值即可。

2.9 If-Match

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

  • 只有当If-Match的字段值跟ETag值匹配一致时,服务器才会接受请求。这时的服务器无法使用弱ETag值。服务器会比对If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,则返回状态码412 Precondition Failed的响应。

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

2.10 If-Modified-Since

  • If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT,如果在If-Modified-Since字段指定的日期时间后,资源发生了更新,服务器会接受请求。

  • 如果请求的资源都没有过更新,则返回状态码304 Not Modified的响应。

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

2.11 If-None-Match

  • 首部字段If-None-Match属于附带条件之一。它和首部字段If-Match作用相反。用于指定If-None-Match字段值的实体标记值与请求资源的ETag不一致时,它就告知服务器处理该请求。 在GET或HEAD方法中使用首部字段If-None-Match可获取最新的资源。因此,这与使用首部字段If-Modified-Since时有些类似。

2.12 If-Range

  • 首部字段If-Range属于附带条件之一。它告知服务器若指定的If-Range字段值(ETag 值或者时间)和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。
  • 不使用首部字段If-Range发送请求的情况:服务器端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当然,范围请求作为前提是无效的。这时,服务器会暂且以状态码412 Precondition Failed作为响应返回,其目的是催促客户端再次发送请求。与使用首部字段If-Range比起来,就需要花费两倍的功夫。

2.13 If-Unmodified-Since

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

2.14 Max-Forwards

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

2.15 Proxy-Authorization

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

2.16 Range

  • Range: bytes=5001-10000,对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。示例表示请求获取从第5001字节至第10000字节的资源。
  • 接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码为206 Partial Content的响应。无法处理该范围请求时,则会返回状态码200 OK的响应及全部资源。

2.17 Referer

  • Referer: http://www.hackr.jp/index.htm,首部字段Referer会告知服务器请求的原始资源的URI。
  • 因为原始资源的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则有可能导致保密信息的泄露。

2.18 TE

  • TE: gzip, deflate;q=0.5,首部字段TE会告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段Accept-Encoding的功能很相像,但是用于传输编码。
  • TE: trailers,首部字段TE除指定传输编码之外,还可以指定伴随trailer字段的分块传输编码的方式。应用后者时,只需把trailers赋值给该字段值。

2.19 User-Agent

  • 首部字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。
  • 由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。

3. 响应首部字段

首部字段名 说明
Accept-Range 是否接收字节范围的请求
Age 推算资源创建经过的时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息

3.1 Accept-Ranges

  • Accept-Ranges: bytes Accept-Ranges: none,首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。 可指定的字段值有两种,可处理范围请求时指定其为bytes,反之则指定其为none。

3.2 Age

  • 首部字段Age能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。 若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段 Age。

3.3 ETag

  • ETag: "82e22293907ce725faf67773957acd12",首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag值。另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。

  • ETag中有强ETag值和弱ETag值之分。

3.4 Location

  • Location: http://www.usagidesign.jp/sample.html,首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。 基本上,该字段会配合3xx :Redirection的响应,提供重定向的URI。 几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。

3.5 Proxy-Authenticate

  • Proxy-Authenticate: Basic realm="Usagidesign Auth",首部字段Proxy-Authenticate会把由代理服务器所要求的认证信息发送给客户端。 它与客户端和服务器之间的HTTP访问认证的行为相似,不同之处在于其认证行为是在客户端与代理之间进行的。而客户端与服务器之间进行认证时,首部字段WWW-Authorization有着相同的作用。

3.6 Retry-After

  • Retry-After: 120,首部字段Retry-After告知客户端应该在多久之后再次发送请求。主要配合状态码503 Service Unavailable响应,或3xx Redirect响应一起使用。 字段值可以指定为具体的日期时间(Wed, 04 Jul 2012 06:34:24 GMT 等格式),也可以是创建响应后的秒数。

3.7 Server

  • Server: Apache/2.2.6 (Unix) PHP/5.2.5,首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。

3.8 Vary

  • Vary: Accept-Language,首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。 从代理服务器接收到源服务器返回包含Vary指定项的响应之后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。

3.9 WWW-Authenticate

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

4. 实体首部字段

首部字段名 说明
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位:字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间

4.1 Allow

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

4.2 Content-Encoding

  • Content-Encoding: gzip,首部字段Content-Encoding会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行 的压缩。
    • gzip(GUN zip)
    • compress(UNIX系统的标准压缩)
    • deflate(zlib)
    • identity(不进行编码)

4.3 Content-Language

  • Content-Language: zh-CN,首部字段Content-Language会告知客户端,实体主体使用的自然语言。

4.4 Content-Length

  • Content-Length: 15000,首部字段Content-Length表明了实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。由于实体主体大小的计算方法略微复杂,所以在此不再展开。

4.5 Content-Location

  • Content-Location: http://www.hackr.jp/index-ja.html,首部字段Content-Location给出与报文主体部分相对应的 URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。 比如,对于使用首部字段Accept-Language的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI(访问http://www.hackr.jp/返回的对象却是http://www.hackr.jp/index-ja.html等类似情况)。

4.6 Content-MD5

  • Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==,首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
  • 对报文主体执行MD5算法获得的128位二进制数,再通过Base64编码后将结果写入Content-MD5字段值。由于HTTP首部无法记录二进制值,所以要通过Base64编码处理。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的MD5算法。计算出的值与首部字段Content-MD5的值作比较后,即可判断出报文主体的准确性。
  • 采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。其中一个原因在于,内容如果能够被篡改,那么同时意味着Content-MD5也可重新计算然后被篡改。所以处在接收阶段的客户端是无法意识到报文主体以及首部字段Content-MD5是已经被篡改过的。

4.7 Content-Range

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

4.8 Content-Type

  • Content-Type: text/html; charset=UTF-8,首部字段Content-Type说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值。 参数charset使用iso-8859-1或euc-jp等字符集进行赋值。

4.9 Expires

  • Expires: Wed, 04 Jul 2012 08:26:05 GMT,首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。 源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。 但是,当首部字段Cache-Control有指定max-age指令时,比起首部字段Expires,会优先处理max-age指令。

4.10 Last-Modified

  • Last-Modified: Wed, 23 May 2012 09:59:55 GMT,首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。

5. 非HTTP/1.1首部字段

在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。还有Cookie、Set-Cookie 和Content-Disposition等在其他RFC中定义的首部字段,它们的使用频率也很高。 这些非正式的首部字段统一归纳在RFC4229 HTTP Header Field Registrations中。

  • 调用Cookie时,由于可校验Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie内的数据不会因来自其他Web站点和攻击者的攻击而泄露。
首部字段名 说明 首部类型
Set-Cookie 开始状态管理所使用的Cookie信息 响应首部类型
Cookie 服务器接收到的Cookie信息 请求首部类型
  • Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; pat,Set-Cookie字段的属性如下。
属性 说明
NAME=VALUE 赋予Cookie的名称和其值(必须项)
expires=DATE Cookie的有效期(若不明确指定则默认为浏览器关闭为止)
path=PATH 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录)
domain=域名 作为Cookie适用对象的域名(若不指定则默认为创建Cookie的服务器的域名)
Secure 仅在HTTPS安全通信时才会发送Cookie
HttpOnly 加以限制,使Cookie不能被JavaScript脚本访问
  • expires属性:Cookie的expires属性指定浏览器可发送Cookie的有效期。 当省略expires属性时,其有效期仅限于维持浏览器会话时间段内。这通常限于浏览器应用程序被关闭之前。 另外,一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显式删除Cookie的方法。但可通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。
  • path属性:Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。不过另有办法可避开这项限制,看来对其作为安全机制的效果不能抱有期待。
  • domain属性:通过Cookie的domain属性指定的域名可做到与结尾匹配一致。比如,当指定example.com 后,除example.com以外,www.example.comwww2.example.com等都可以发送Cookie。 因此,除了针对具体指定的多个域名发送Cookie之外,不指定domain属性显得更安全。
  • secure属性:Set-Cookie: name=value; secure,Cookie的secure属性用于限制Web页面仅在HTTPS安全连接时,才可以发送Cookie。
  • HttpOnly属性:Set-Cookie: name=value; HttpOnly,Cookie的HttpOnly属性是Cookie的扩展功能,它使JavaScript脚本无法获得Cookie。其主要目的为防止跨站脚本攻击(Cross-site scripting,XSS)对Cookie的信息窃取。
  • Cookie: status=enable,首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。

5.2 其他首部字段

  • HTTP首部字段是可以自行扩展的。所以在Web服务器和浏览器的应用上,会出现各种非标准的首部字段。 接下来,我们就一些最为常用的首部字段进行说明。
    • X-Frame-Options
    • X-XSS-Protection
    • DNT
    • P3P
  • 在HTTP等多种协议中,通过给非标准参数加上前缀X-,来区别于标准参数,并使那些非标准的参数作为扩展变成可能。但是这种简单粗暴的做法有百害而无一益,然而,对已经在使用中的X-前缀来说,不应该要求其变更。
5.2.1 X-Frame-Options
  • X-Frame-Options: DENY,首部字段X-Frame-Options属于HTTP响应首部,用于控制网站内容在其他Web网站的Frame标签内的显示问题。其主要目的是为了防止点击劫持攻击。 首部字段X-Frame-Options有以下两个可指定的字段值。
    • DENY :拒绝
    • SAMEORIGIN :仅同源域名下的页面匹配时许可。
  • 能在所有的Web服务器端预先设定好X-Frame-Options字段值是最理想的状态。
5.2.2 X-XSS-Protection
  • X-XSS-Protection: 1,首部字段X-XSS-Protection属于HTTP响应首部,它是针对跨站脚本攻击XSS的一种对策,用于控制浏览器XSS防护机制的开关。
  • 首部字段X-XSS-Protection可指定的字段值如下。
    • 0 :将XSS过滤设置成无效状态。
    • 1 :将XSS过滤设置成有效状态。
5.2.3 DNT
  • DNT: 1,首部字段DNT属于HTTP请求首部,其中DNT是Do Not Track的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
  • 首部字段 DNT 可指定的字段值如下。
    • 0 :同意被追踪。
    • 1 :拒绝被追踪。
  • 由于首部字段DNT的功能具备有效性,所以Web服务器需要对DNT做对应的支持。
5.2.4 P3P
  • P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS ,首部字段P3P属于HTTP响应首部,通过利用P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,可以让Web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。 要进行P3P的设定,需按以下操作步骤进行。
    • 步骤 1:创建P3P隐私。
    • 步骤 2:创建P3P隐私对照文件后,保存命名在/w3c/p3p.xml
    • 步骤 3:从P3P隐私中新建Compact policies后,输出到HTTP响应中。

第 7 章 确保Web安全的HTTPS

SSL:Secure Socket Layer,安全套接层

TSL:Transport Layer Security,安全层传输协议

DOS:Denial of Service,拒绝服务攻击

EV SSL证书(Extended Validation SSL Certificate):用来证明作为通信一方的服务器是否规范,确认对方服务器背后运营的企业是否真实存在

CRL:Certificate Revocation List,将证书无效化的证书吊销列表

RCA:Root Certificate Authority,从客户端删除根证书颁发机构

IETF:Internet Engineering Task Force,Internet 工程任务组


  • HTTP的缺点:
    • 通信使用明文(不加密),内容可能会被窃听。
    • 不验证通信方的身份,因此有可能遭遇伪装。
      • 无法确定各自身份是否真实。
      • 无法确定通信的一方是否具备访问权限。
      • 无法判断请求来自何方,出自谁手。
      • 即使是无意义的请求也会照单全收。无法阻止海量请求下的DoS攻击。
    • 无法证明报文的完整性,所以有可能已遭篡改。
  • 加密处理防止被窃听的两种方式:
    • 通信的加密:一种方式就是将通信加密。HTTP协议中没有加密机制,但可以通过和 SSL或 TLS的组合使用, 加密HTTP的通信内容。 用SSL建立安全通信线路之后,就可以在这条线路上进行HTTP通信了。与SSL组合使用的HTTP被称为HTTPS(HTTP Secure,超文本传输安全协议)或HTTP over SSL。
    • 内容的加密:对报文内容加密,为了做到有效的内容加密,前提是要求客户端和服务器同时具备加密和解密机制,但是内容仍有被篡改的风险。
  • 请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击(Man-in-the-Middle attack,MITM)。
  • 防止内容被篡改的常用方法:MD5和SHA-1等散列值校验的方法,以及用来确认文件的数字签名方法。提供文件下载服务的Web网站也会提供相应的以PGP(Pretty Good Privacy,完美隐私)创建的数字签名及MD5算法生成的散列值。PGP是用来证明创建文件的数字签名,MD5是由单向函数生成的散列值。不论使用哪一种方法,都需要操纵客户端的用户本人亲自检查验证下载的文件是否就是原来服务器上的文件。 浏览器无法自动帮用户检查。 可惜的是,用这些方法也依然无法百分百保证确认结果正确。因 为PGP和MD5本身被改写的话,用户是没有办法意识到的。 为了有效防止这些弊端,有必要使用HTTPS。SSL提供认证和加密处理及摘要功能。仅靠HTTP确保完整性是非常困难的,因此通过和其他协议组合使用来实现这个目标。
  • HTTP+加密+认证+完整性保护=HTTPS。
  • HTTPS只是 HTTP 通信接口部分用SSL和 TLS协议代替而已。通常,HTTP直接和TCP通信。当使用 SSL时,则演变成先和 SSL通信,再由SSL和TCP通信了。
  • SSL采用一种叫做公开密钥加密的加密处理方式。
    • 共享密钥加密:加密和解密同用一个密钥的方式称为共享密钥加密,也被叫做对称密钥加密。但是如何把共享密匙传递给对方存在风险。
    • 公开密钥加密方式:公开密钥加密使用一对非对称的密钥。一把叫做私有密钥,另一把叫做公开密钥。私有密钥不能让其他任何人知道,而公开密钥任何人都可以获得。使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
    • HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
  • 证明公开密钥正确性的证书:公开密钥加密方式还是存在一些问题的。那就是无法证明公开密钥本身就是货真价实的公开密钥。首先,服务器的运营人员向数字证书认证机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。 服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。公钥证书也可叫做数字证书或直接称为证书。 接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事: 一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二, 服务器的公开密钥是值得信赖的。 此处认证机关的公开密钥必须安全地转交给客户端。使用通信方式时,如何安全转交是一件很困难的事,因此,多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。

  • 持有EV SSL证书的Web网站的浏览器地址栏处的背景色是绿色的。
  • 独立构建的认证机构叫做自认证机构,由自认证机构颁发的证书也被戏称为自签名证书。浏览器访问持有自签名证书的服务器时,会显示”无法确认连接安全性”或”该网站的安全证书存在问题”等警告消息。
  • HTTPS 的通信步骤:
    1. 客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件列表(所使用的加密算法及密钥长度等)。
    2. 服务器可进行SSL通信时,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
    3. 之后服务器发送Certificate报文。报文中包含公开密钥证书。
    4. 最后服务器发送Server Hello Done报文通知客户端,最初阶段的SSL握手协商部分结束。
    5. SSL第一次握手结束之后,客户端以Client Key Exchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开密钥进行加密。
    6. 接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密。
    7. 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
    8. 服务器同样发送Change Cipher Spec报文。
    9. 服务器同样发送Finished报文。
    10. 服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到 SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
    11. 应用层协议通信,即发送HTTP响应。
    12. 最后由客户端断开连接。断开连接时,发送close_notify报文。这步之后再发送TCP FIN报文来关闭与TCP的通信。
  • 在以上流程中,应用层发送数据时会附加一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性。

  • IETF以SSL3.0为基准,后又制定了TLS1.0、TLS1.1和TLS1.2。TSL是以SSL为原型开发的协议,有时会统一称该协议为SSL。当前主流的版本是SSL3.0和TLS1.0。
  • SSL的慢分两种。一种是指通信慢。另一种是指由于大量消耗CPU及内存等资源,导致处理速度变慢。

第 8 章 确认访问用户身份的认证

  • 需要核对的信息通常是指以下这些:

    • 密码:只有本人才会知道的字符串信息。
    • 动态令牌:仅限本人持有的设备内显示的一次性密码。
    • 数字证书:仅限本人(终端)持有的信息。
    • 生物认证:指纹和虹膜等本人的生理信息。
    • IC卡等:仅限本人持有的信息。
  • HTTP/1.1使用的认证方式如下所示:

    • BASIC认证(基本认证)
    • DIGEST认证(摘要认证)
    • SSL客户端认证
    • FormBase认证基于(表单认证)
  • BASIC认证(基本认证):BASIC认证(基本认证)是从HTTP/1.0就定义的认证方式。即便是现在仍有一部分的网站会使用这种认证方式。是Web服务器与通信客户端之间进行的认证方式。步骤如下:

    • 步骤1:当请求的资源需要BASIC认证时,服务器会随状态码401 Authorization Required,返回带WWW-Authenticate首部字段的响应。 该字段内包含认证的方式BASIC及Request-URI安全域字符串realm。
    • 步骤2: 收到状态码401的客户端为了通过BASIC认证,需要将用户ID及密码发送给服务器。发送的字符串内容是由用户ID和密码构成,两者中间以冒号连接后,再经过Base64编码处理。把这串字符串写入首部字段Authorization后,发送请求。 当用户代理为浏览器时,用户仅需输入用户ID和密码即可,之后, 浏览器会自动完成到Base64编码的转换工作。
    • 步骤3:接收到包含首部字段Authorization请求的服务器,会对认证信息的正确性进行验证。如验证通过,则返回一条包含Request-URI资源的响应。BASIC认证虽然采用Base64编码方式,但这不是加密处理。不需要任何附加信息即可对其解码。由于明文解码后就是用户ID和密码,在HTTP等非加密通信的线路上进行BASIC认证的过程中,如果被人窃听,被盗的可能性极高。 另外,除此之外想再进行一次BASIC认证时,一般的浏览器却无法实现认证注销操作,这也是问题之一。BASIC认证使用上不够便捷灵活,且达不到多数Web网站期望的安全性等级,因此它并不常用。
  • DIGEST认证:从HTTP/1.1起就有了DIGEST认证。DIGEST认证同样使用质询/响应的方式,但不会像BASIC认证那样直接发送明文密码。 所谓质询响应方式是指,一开始一方会先发送认证要求给另一方,接着使用从另一方那接收到的质询码计算生成响应码。最后将响应码返回给对方进行认证的方式。因为发送给对方的只是响应摘要及由质询码产生的计算结果,所以比起BASIC认证,密码泄露的可能性就降低了。DIGEST认证的认证步骤如下。

    • 步骤1:请求需认证的资源时,服务器会随着状态码401 Authorization Required,返回带WWW-Authenticate首部字段的响应。 该字段内包含质问响应方式认证所需的临时质询码(随机数,nonce)。首部字段WWW-Authenticate内必须包含realm和nonce这两个字段的信息。客户端就是依靠向服务器回送这两个值进行认证的。nonce是一种每次随返回的401响应生成的任意随机字符串。该字符串通常推荐由 Base64编码的十六进制数的组成形式,但实际内容依赖服务器的具体实现。
    • 步骤2:接收到401状态码的客户端,返回的响应中包含DIGEST认证必须的首部字段Authorization信息。 首部字段Authorization内必须包含username、realm、nonce、uri和response的字段信息。其中realm和nonce就是之前从服务器接收到的响应中的字段。username是realm限定范围内可进行认证的用户名。uri(digest-uri)即Request-URI的值,但考虑到经代理转发后Request-URI的值可能被修改,因此事先会复制一份副本保存在uri内。response也可叫做Request-Digest,存放经过MD5运算后的密码字符串,形成响应码。 另外,有关Request-Digest的计算规则较复杂。
    • 步骤3:接收到包含首部字段Authorization请求的服务器,会确认认证信息的正确性。认证通过后则返回包含Request-URI资源的响应。并且这时会在首部字段Authentication-Info写入一些认证成功的相关信 息。DIGEST认证提供了高于BASIC认证的安全等级,但是和HTTPS的客户端认证相比仍旧很弱。DIGEST认证提供防止密码被窃听的保护机制,但并不存在防止用户伪装的保护机制。 DIGEST认证和BASIC认证一样,使用上不那么便捷灵活,且仍达不到多数Web网站对高度安全等级的追求标准。因此它的适用范围也有所受限。
  • SSL客户端认证:从使用用户ID和密码的认证方式方面来讲,只要二者的内容正确, 即可认证是本人的行为。但如果用户ID和密码被盗,就很有可能被第三者冒充。利用 SSL客户端认证则可以避免该情况的发生。SSL客户端认证是借由HTTPS的客户端证书完成认证的方式。凭 客户端证书认证,服务器可确认访问是否来自已登录的客户端。 SSL客户端认证的认证步骤:为达到 SSL客户端认证的目的,需要事先将客户端证书分发给客户 端,且客户端必须安装此证书。

    • 步骤1:接收到需要认证资源的请求,服务器会发送Certificate Request报文,要求客户端提供客户端证书。
    • 步骤2:用户选择将发送的客户端证书后,客户端会把客户端证书信息以Client Certificate报文方式发送给服务器。
    • 步骤3:服务器验证客户端证书验证通过后方可领取证书内客户端的公开密钥,然后开始HTTPS加密通信。
  • SSL客户端认证采用双因素认证:在多数情况下,SSL客户端认证不会仅依靠证书完成认证,一般会和基于表单认证组合形成一种双因素认证来使用。所谓双因素认证就是指,认证过程中不仅需要密码这一个因素,还需要申请认证者提供其他持有信息,从而作为另一个因素,与其组合使用的认证方式。换言之,第一个认证因素的SSL客户端证书用来认证客户端计算机, 另一个认证因素的密码则用来确定这是用户本人的行为。 通过双因素认证后,就可以确认是用户本人正在使用匹配正确的计算机访问服务器。

  • 基于表单认证:基于表单的认证方法并不是在HTTP协议中定义的。客户端会向服务器上的Web应用程序发送登录信息,按登录信息的验证结果认证。根据Web应用程序的实际安装,提供的用户界面及认证方式也各不 相同。

  • 由于使用上的便利性及安全性问题,HTTP协议标准提供的BASIC认证和DIGEST认证几乎不怎么使用。另外,SSL客户端认证虽然具有高度的安全等级,但因为导入及维持费用等问题,还尚未普及。 比如SSH和FTP协议,服务器与客户端之间的认证是合乎标准规范的,并且满足了最基本的功能需求上的安全使用级别,因此这些协议的认证可以拿来直接使用。但是对于Web网站的认证功能,能够满足其安全使用级别的标准规范并不存在,所以只好使用由Web应用程序各自实现基于表单的认证方式。不具备共同标准规范的表单认证,在每个Web网站上都会有各不相同的实现方式。如果是全面考虑过安全性能而实现的表单认证,那么就能够具备高度的安全等级。

  • Session管理及Cookie应用:基于表单认证的标准规范尚未有定论,一般会使用Cookie来管理Session(会话)。 基于表单认证本身是通过服务器端的Web应用,将客户端发送过来的用户ID和密码与之前登录过的信息做匹配来进行认证的。但鉴于HTTP是无状态协议,之前已认证成功的用户状态无法通过协议层面保存下来。即无法实现状态管理,因此即使当该用户下一次继续访问,也无法区分他与其他的用户。于是我们会使用Cookie来 管理Session,以弥补HTTP协议中不存在的状态管理功能。

    • 步骤1:客户端把用户ID和密码等登录信息放入报文的实体部分,通常是以POST方法把请求发送给服务器。而这时,会使用HTTPS通信来进行HTML表单画面的显示和用户输入数据的发送。
    • 步骤2:服务器会发放用以识别用户的Session ID。通过验证从客户端发送过来的登录信息进行身份认证,然后把用户的认证状态与Session ID绑定后记录在服务器端。向客户端返回响应时,会在首部字段 Set-Cookie内写入Session ID。 你可以把Session ID想象成一种用以区分不同用户的等位号。 然而,如果 Session ID被第三方盗走,对方就可以伪装成你的身份进行恶意操作了。因此必须防止Session ID被盗或被猜出。为了做到这点,Session ID应使用难以推测的字符串,且服务器端也需要进行有效期的管理,保证其安全性。 另外,为减轻跨站脚本攻击XSS造成的损失,建议事先在Cookie内加上httponly属性。
    • 步骤3:客户端接收到从服务器端发来的Session ID后,会将其作为Cookie保存在本地。下次向服务器发送请求时,浏览器会自动发送Cookie,所以Session ID也随之发送到服务器。服务器端可通过验证接收到的Session ID识别用户和其认证状态。
  • 不仅基于表单认证的登录信息及认证过程都无标准化的方法, 服务器端应如何保存用户提交的密码等登录信息等也没有标准化。 通常,一种安全的保存方法是,先利用给密码加盐(salt)的方式增加额外信息,再使用散列(hash)函数计算出散列值后保存。但是我们也经常看到直接保存明文密码的做法,而这样的做法具有导致密码泄露的风险。

  • salt 其实就是由服务器随机生成的一个字符串,但是要保证长度足够长,并且是真正随机生成的。然后把它和密码字符串相连接生成散列值。当两个用户使用了同一个密码时,由于随机生成的salt值不同,对应的散列值也将是不同的。这样一来,很大程度上减少了密码特征,攻击者也就很难利用自己手中的密码特征库进行破解。

第 9 章 基于HTTP的功能追加协议

  • 消除HTTP瓶颈的SPDY。
  • 使用浏览器进行全双工通信的WebSocket。
  • 期盼已久的HTTP/2.0。
  • Web服务器管理文件的WebDAV。

第 10 章 构建Web内容的技术

1. HTML

  • HTML(超文本标记语言)是为了发送Web上的超文本而开发的标记语言。

  • 标记语言是指通过在文档的某部分穿插特别的字符串标签,用来修饰文档的语言。我们把出现在HTML文档内的这种特殊字符串叫做HTML标签(Tag)。

2. 设计应用CSS

  • CSS(Cascading Style Sheets,层叠样式表)可以指定如何展现HTML内的各种元素,属于样式表标准之一。

3. 动态HTML

  • 动态HTML技术是通过调用客户端脚本语言JavaScript,实现对HTML的Web页面的动态改造。利用 DOM(Document Object Model,文档对象模型)可指定欲发生动态变化的HTML元素。
  • DOM是用以操作HTML文档和XML文档的API(Application Programming Interface,应用编程接口)。使用DOM可以将HTML内的元素当作对象操作,如取出元素内的字符串、改变那个CSS的属性等,使页面的设计发生改变。 通过调用JavaScript等脚本语言对DOM的操作,可以以更为简单的方式控制HTML的改变。

4. Web应用

  • Web应用是指通过Web功能提供的应用程序。
  • 原本应用HTTP协议的Web的机制就是对客户端发来的请求,返回事前准备好的内容。可随着Web越来越普及,仅靠这样的做法已不足以应对所有的需求,更需要引入由程序创建HTML内容的做法。 类似这种由程序创建的内容称为动态内容,而事先准备好的内容称为静态内容。Web应用则作用于动态内容之上。
  • CGI(Common Gateway Interface,通用网关接口)是指Web服务器在接收到客户端发送过来的请求后转发给程序的一组机制。在CGI的作用下,程序会对请求内容做出相应的动作,比如创建HTML等动态内容。使用 CGI的程序叫做CGI程序,通常是用Perl、PHP、Ruby 和C等编程语言编写而成。

5. Servlet

  • Servlet是一种能在服务器上创建动态内容的程序。Servlet是用Java语言实现的一个接口,属于面向企业级 Java(JavaEE,Java Enterprise Edition)的一部分。
  • 之前提及的CGI,由于每次接到请求,程序都要跟着启动一次。因此一旦访问量过大,Web服务器要承担相当大的负载。而Servlet运行在与Web服务器相同的进程中,因此受到的负载较小。Servlet的运行环境叫做Web 容器或 Servlet 容器。
  • Servlet常驻内存,因此在每次请求时,可启动相对进程级别更为轻量的Servlet,程序的执行效率从而变得更高。
  • 随着CGI的普及,每次请求都要启动新CGI程序的CGI运行机制逐渐变成了性能瓶颈,所以之后Servlet和mod_perl等可直接在Web服务器上运行的程序才得以开发、普及。

6. 数据发布的格式及语言

6.1 可扩展标记语言

  • XML(eXtensible Markup Language,可扩展标记语言)是一种可按应用目标进行扩展的通用标记语言。旨在通过使用XML,使互联网数据共享变得更容易。 XML和 HTML都是从标准通用标记语言SGML(Standard Generalized 192Markup Language)简化而成。与HTML相比,它对数据的记录方式做了特殊处理。
  • XML和HTML一样,使用标签构成树形结构,并且可自定义扩展标签。 从XML文档中读取数据比起HTML更为简单。由于XML的结构基本上都是用标签分割而成的树形结构,因此通过语法分析器 的解析功能解析XML结构并取出数据元素,可更容易地对数据进行读取。更容易地复用数据使得XML在互联网上被广泛接受。比如,可用在2个不同的应用之间的交换数据格式化。

6.2 发布更新信息的RSS/Atom

  • RSS(简易信息聚合,也叫聚合内容)和Atom都是发布新闻或博客日志等更新信息文档的格式的总称。两者都用到了XML。

6.3 JavaScript衍生的轻量级易用JSON

JSON(JavaScript Object Notation)是一种 JavaScript的对象表示法为基础的轻量级数据标记语言。能够处理的数据类型有:false/null/true/对象/数组/数字/字符串,这7种类型。{"name": "Web Application Security", "num": "TR001"} ,JSON让数据更轻更纯粹,并且JSON的字符串形式可被JavaScript轻易地读入。当初配合XM使用的Ajax技术也让JSON的应用变得更为广泛。另外,其他各种编程语言也提供丰富的库类,以达到轻便操作JSON的目的。

第 11 章 Web的攻击技术

  • HTTP不具备必要的安全功能。
  • 在客户端即可篡改请求。
  • 针对Web应用的攻击模式:
    • 以服务器为目标的主动攻击
      • SQL注入攻击
      • OS命令注入攻击
    • 以服务器为目标的被动攻击
  • 因输出值转移不完全引发的安全漏洞:
    • 跨站脚本攻击XSS:指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的HTML标签或JavaScript进行的一种攻击。
      • 利用虚假输入表单骗取用户个人信息。
      • 利用脚本窃取用户的 Cookie 值,被害者在不知情的情况下, 帮助攻击者发送恶意请求。
      • 显示伪造的文章或图片。
    • SQL注入攻击:是指针对Web应用使用的数据库,通过运行非法的SQL而产生的攻击。
      • 非法查看或篡改数据库内的数据。
      • 规避认证。
      • 执行和数据库服务器业务关联的程序等。
    • OS命令注入攻击:是指通过Web应用,执行非法的操作系统命令达到攻击的目的。只要在能调用Shell函数的地方就有存在被攻击的风险。
    • HTTP首部注入攻击:是指攻击者通过在响应首部字段内插入换行,添加任意响应首部或主体的一种攻击。属于被动攻击模式。
      • 设置任何Cookie信息。
      • 重定向至任意URL。
      • 显示任意的主体(HTTP 响应截断攻击)。
    • 邮件首部注入攻击:是指Web应用中的邮件发送功能,攻击者通过向邮件首部To或Subject内任意添加非法内容发起的攻击。利用存在安全漏洞的Web网站,可对任意邮件地址发送广告邮件或病毒邮件。
    • 目录遍历攻击:目录遍历攻击是指对本无意公开的文件目录, 通过非法截断其目录路径后,达成访问目的的一种攻击。
    • 因设置或设计上的缺陷引发的安全漏洞:
      • 强制浏览:从安置在Web服务器的公开目录下的文件中,浏览那些原本非自愿公开的文件。
      • 不正确的错误消息处理:Web应用的错误信息内包含对攻击者有用的信息。
      • 开放重定向:是一种对指定的任意URL作重定向跳转的功能。假如指定的重定向URL到某个具有恶意的Web网站,那么用户就会被诱导至那个Web网站。
    • 因会话管理疏忽引发的安全漏洞:
      • 会话劫持:攻击者通过某种手段拿到了用户的会话ID,并非法使用此会话ID伪装成用户,达到攻击的目的。
      • 会话固定攻击:对以窃取目标会话ID为主动攻击手段的会话劫持而言,会话固定攻击攻击会强制用户使用攻击者指定的会话ID,属于被动攻击。
      • 跨站点请求伪造:攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击。
    • 其他安全漏洞:
      • 密码破解:穷举法、字典攻击。
      • 点击劫持:是指利用透明的按钮或链接做成陷阱,覆盖在Web页面之上。然后诱使用户在不知情的情况下,点击那个链接访问内容的一种攻击手段。
      • DoS攻击:让运行中的服务呈停止状态的攻击。
        • 集中利用访问请求造成资源过载,资源用尽的同时,实际上服务也就呈停止状态。
        • 通过攻击安全漏洞使服务停止。
      • 后门程序:指开发设置的隐藏入口,可不按正常步骤使用受限功能。利用后门程序就能够使用原本受限制的功能。