HTTP协议 - 重学计算机网络系列(3)

前言

  • 学习资料来源于《图解HTTP》。
  • 部分内容参考于: 前端基础篇之HTTP协议
  • 本篇文章性质为笔记,总结。

    Web及网络基础

    WWW

    1989年3月,HTTP诞生了。
CERN(欧洲核子研究组织)的蒂姆·伯纳斯-李(TimBerners-Lee)博士提出了一种能让远隔两地的研究者们共享知识的设想。

最初设想的基本理念是:借助多文档之间相互关联形成的超文本(HyperText),连成可相互参阅的WWW(World Wide Web,万维网)。

WWW这一名称,是Web浏览器当年用来浏览超文本的客户端应用程序时的名称。现在则用来表示这一系列的集合,也可简称为Web。

现在已提出了3项WWW构建技术,分别是:页面的文本标记语言的HTML(HyperText Markup Language,超文本标记语言);作为文档传递协议的HTTP;指定文档所在地址的URL(Uniform Resource Locator,统一资源定位符)。

总结:WWW = Web = HTML + HTTP + URL。

HTTP

  • HTTP/0.9
    HTTP于1990年问世。那时的HTTP并没有作为正式的标准被建立。这时的HTTP其实含有HTTP/1.0之前版本的意思,因此被称为HTTP/0.9。

  • HTTP/1.0
    HTTP正式作为标准被公布是在1996年的5月,版本被命名为HTTP/1.0,并记载于RFC1945。虽说是初期标准,但该协议标准至今仍被广泛使用在服务器端。

  • HTTP/1.1
    1997年1月公布的HTTP/1.1是目前主流的HTTP协议版本。当初的标准是RFC2068,之后发布的修订版RFC2616就是当前的最新版本。

HTTP/2.0 下一篇会讲到。

网络基础TCP/IP

TCP/IP是互联网相关的各类协议族的总称。而不是单指TCP和IP两个协议。

应用层

应用层决定了向用户提供应用服务时通信的活动。

传输层

传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。

在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据报协议)。

网络层

网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。

与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。

链路层

用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。

传输过程

与HTTP关系密切的协议:IP、TCP和DNS

负责传输的IP协议

IP协议位于网络层。
TCP/IP协议族中的IP指的就是网际协议。
可能有人会把“IP”和“IP地址”搞混,“IP”其实是一种协议的名称。

IP协议的作用是把各种数据包传送给对方。但是IP协议用什么来确定传输的数据包要发到谁手中在呢?要保证确实传送到对方那里,则需要满足各类条件。其中两个重要的条件是IP地址MAC地址(Media Access ControlAddress)。

IP地址指明了节点被分配到的地址,MAC地址是指网卡所属的固定地址。
IP地址可以和MAC地址进行配对。IP地址可变换,但MAC地址基本上不会更改。

使用ARP协议凭借MAC地址进行通信

ARP是一种用以解析地址的协议,根据通信方的IP地址就可以反查出对应的MAC地址。在进行中转时,会利用下一站中转设备的MAC地址来搜索下一个中转目标。

IP协议利用MAC通信

确保可靠性的TCP协议

TCP位于传输层,提供可靠的字节流服务。

所谓的字节流服务是指,为了方便传输,将大块数据分割成以报文段为单位的数据包进行管理。而可靠的传输服务是指,能够把数据准确可靠地传给对方。一言以蔽之,TCP协议为了更容易传送大数据才把数据分割,而且TCP协议能够确认数据最终是否送达到对方

如何保证数据能到达目标?TCP协议采用了三次握手策略。

三次握手

用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了TCP的标志(flag)——SYN(synchronize)和ACK(acknowledgement)。

发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。

若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。

三次握手

除了上述三次握手,TCP协议还有其他各种手段来保证通信的可靠性。

DNS域名解析

DNS在系列2已经讲过就不在赘述。

各种协议关系一目了然

各种协议关系

URL

绝对URL格式

  • 协议方案名。
    使用http:或https:等协议方案名获取访问资源时要指定协议类型。不区分字母大小写,最后附一个冒号(:)。
    也可使用data:或javascript:这类指定数据或脚本程序的方案名
  • 登录信息(认证)
    指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份认证)。此项是可选项。
  • 服务器地址
    使用绝对URI必须指定待访问的服务器地址。地址可以是类似hackr.jp这种DNS可解析的名称,或是192.168.1.1这类IPv4地址名,还可以是[0:0:0:0:0:0:0:1]这样用方括号括起来的IPv6地址名
  • 查询字符串
    针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。此项可选。
  • 片段标识符
    使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个位置)。但在RFC中并没有明确规定其使用方法。该项也为可选项。

简单的HTTP基础

请求报文和响应报文

HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。


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


在起始行开头的HTTP/1.1表示服务器对应的HTTP版本。紧挨着的200 OK 表示请求的处理结果的状态码和原因短语)。下一行显示了创建响应的日期时间,是首部字段内的一个属性。接着以一空行分隔,之后的内容称为资源实体的主体。

无状态的HTTP

HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。

为什么要这样做?

使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。
协议本身并不保留之前一切的请求或响应报文的信息。
这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。

HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管理状态了。

请求URI定位资源

HTTP协议使用URI定位互联网上的资源。正是因为URI的特定功能,在互联网上任意位置的资源都能访问到。

客户请求资源的时候,请求报文需要指定URL,有以下几种方法。

  • 完整请求。
    GET http://hacker.jp/index/html HTTP/1.1
  • 在HOST写明网络域名或IP地址。
    GET /index.htm HTTP/1.1 HOST:hacker.jp
  • 此之外,如果不是访问特定资源而是对服务器本身发起请求,可以用一个*来代替请求URI。
    OPTIONS * HTTP/1.1

告知服务器意图的HTTP方法

  • GET:获取资源。
    GET方法用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;如果是像CGI(CommonGateway Interface,通用网关接口)那样的程序,则返回经过执行后的输出结果

  • POST:传输实体内容。
    虽然用GET方法也可以传输实体的主体,但一般不用GET方法进行传输,而是用POST方法。虽说POST的功能与GET很相似,但POST的主要目的并不是获取响应的主体内容。

  • PUT:传输文件
    PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置

    但是,鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的Web网站不使用该方法。

  • HEAD: 获取报文首部

HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等。

  • DELETE:删除文件
    DELETE方法用来删除文件,是与PUT相反的方法。DELETE方法按请求URI删除指定的资源。

    但是,HTTP/1.1的DELETE方法本身和PUT方法一样不带验证机制,所以一般的Web网站也不使用DELETE方法。当配合Web应用程序的验证机制,或遵守REST标准时还是有可能会开放使用的。

  • OPTIONS:询问支持的方法
    OPTIONS方法用来查询针对请求URI指定的资源支持的方法。
    响应报文会返回当前服务器所支持的方法:比如 Allow:GET,POST,HEAD,OPTIONS

  • TRACE: 追踪路径
    发送请求时,在Max-Forwards首部字段中填入数值,每经过一个服务器端就将该数字减1,当数值刚好减到0时,就停止继续传输,最后接收到请求的服务器端则返回状态码200 OK的响应。

客户端通过TRACE方法可以查询发送出去的请求是怎样被加工修改/篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理中转,TRACE方法就是用来确认连接过程中发生的一系列操作

但是,TRACE方法本来就不怎么常用,再加上它容易引发XST(Cross-Site Tracing,跨站追踪)攻击,通常就更不会用到了。

  • CONNECT:要求用隧道协议连接代理
    CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(SecureSockets Layer,安全套接层)和TLS(Transport LayerSecurity,传输层安全)协议把通信内容加密后经网络隧道传输。

持久连接节省通信量

HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使这样也没有多大问题。可随着HTTP的普及,文档中包含大量图片的情况多了起来。比如,使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问HTML页面资源的同时,也会请求该HTML页面里包含的其他资源。因此,每次的请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。

为解决上述TCP连接的问题,HTTP/1.1和一部分的HTTP/1.0想出了持久连接(也称为HTTP keep-alive)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态

持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使HTTP请求和响应能够更早地结束,这样Web页面的显示速度也就相应提高了。

在HTTP/1.1中,所有的连接默认都是持久连接。HTTP/1.0 则不一定。

HTTP是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。

Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态,用来让服务端记住客户端。

Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。
服务器端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息

过程:

  • 请求报文(首次请求)
    ```
    GET /reader/ HTTP/1.1
    HOST: hacker.jp
  • 首部字段内没有Cookie的相关信息
    ```
  • 响应报文(服务端生成Cookie信息)

    HTTP/1.1 200 OK
    .....
    server: Apache <Set-Cookie: sid=12313123121; path=/; .......>
  • 请求报文(第二次请求)

    GET /image/ HTTP/1.1
    Host: hacker.jp
    Cookie: sid=12313123121
    这样二次请求的时候,服务端通过cookie会记住上一次访问的是谁

状态码

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。

只要遵守状态码类别的定义,即使改变RFC2616中定义的状态码,或服务器端自行创建状态码都没问题。

仅记录在RFC2616上的HTTP状态码就达40种,若再加上WebDAV和附加HTTP状态码等扩展,数量就达60余种。别看种类繁多,实际上经常使用的大概只有14种。

2XX成功

  • 200 OK
    表示从客户端发来的请求在服务器端被正常处理了。

  • 204 No Content
    表示请求处理成功,但没有资源可以返回。(响应报文中并没有主体资源,或者并不允许返回任何资源)比如,当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新。

    一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。

  • 206 Partial Content
    该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。

3XX 重定向

3XX响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。

  • 301 永久性重定向。
    该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。也就是说,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。

  • 302 临时性重定向
    该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。

和301 Moved Permanently状态码相似,但302状态码代表的资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的URI将来还有可能发生改变。比如,用户把URI保存成书签,但不会像301状态码出现时那样去更新书签,而是仍旧保留返回302状态码的页面对应的URI。

  • 303 See Other
    该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。
    303状态码和302 Found状态码有着相同的功能,但303状态码明确表示客户端应当采用GET方法获取资源,这点与302状态码有区别。

比如,当使用POST方法访问CGI程序,其执行后的处理结果是希望客户端能以GET方法重定向到另一个URI上去时,返回303状态码。虽然302 Found状态码也可以实现相同的功能,但这里使用303状态码是最理想的。

  • 304 Not Modified
    该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304 Not Modified。

304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。

附带条件的请求是指采用GET方法的请求报文中包含if-Match,if-Modified-Since,if-None-Match,if-Range,if-Unmodified-Since中任一首部。

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

4XX 客户端错误

4XX的响应结果表明客户端是发生错误的原因所在。

  • 400 Bad Request
    状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像200 OK一样对待该状态码。

  • 401 Unauthorized
    该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息

    • 若第一次返回401,会弹出认证的对话框。
    • 第二次返回401,表示认证失败。
  • 403 Forbidden
    该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。

    未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举的情况都可能是发生403的原因。

  • 404 Not Found
    该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。

5XX 服务器错误

5XX的响应结果表明服务器本身发生错误。

  • 500 Internal Server Error
    该状态码表明服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障。

  • 503 Service Unavailable
    该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入Retry-After首部字段再返回给客户端。

不少返回的状态码响应都是错误的,但是用户可能察觉不到这点。比如Web应用程序内部发生错误,状态码依然返回200 OK,这种情况也经常遇到。

Web服务器

一台Web服务器可搭建多个独立域名的Web网站,也可作为通信路径上的中转度武器提升传输效率。

用单台虚拟主机实现多个域名

HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。即一个服务器可以为每位客户持有的域名运行各自不同的网站。这是因为利用了虚拟主机的功能。

即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器。

www.baidu.com/www.cctv.com/同时部署在同一个服务器上,使用DNS解析域名后,两者的访问IP地址会相同。

在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。

通信数据转发

HTTP通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理、网关和隧道。它们可以配合服务器工作。

这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。

代理

代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理不改变请求URI,会直接发送给前方持有资源的目标服务器。

持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过代理服务器后再传给客户端。

为什么要使用代理?

  • 利用缓存技术减少网络带宽的流量。
  • 组织内部针对特定网站的访问控制,以获取访问日志为主要目的

代理转发响应时,缓存代理会预先将资源的副本(缓存)保存在代理服务器上。当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。

网关

网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务

为什么要用网关?
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。

隧道

隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。

隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。

缓存

缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,因此也就节省了通信流量和通信时间。

缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处理相同的请求了。

缓存有效期

即便缓存服务器内有缓存,也不能保证每次都会返回对同资源的请求。因为这关系到被缓存资源的有效性问题。

当遇上源服务器上的资源更新时,如果还是使用不变的缓存,那就会演变成返回更新前的“旧”资源了。

即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取“新”资源。

客户端的缓存

缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。

浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。
比如在系列1中提到过,DNS解析的时候,当在浏览器输入地址后,不会直接进行解析,会在本地缓存中对比是否有访问对象的IP地址,有的话就不用DNS解析,直接就可以拿到IP地址。

HTTP报文首部

请求报文首部组成
请求报文 = 报文首部 + 报文主体
报文首部 = (方法 + URI + HTTP版本) + (请求首部字段 + 通用首部字段 + 实体首部字段)

响应报文首部组成
响应报文 = 报文首部 + 主体
报文首部 = (HTTP版本 + 状态码) + (响应首部字段 + 通用首部字段 + 实体首部字段)

首部字段类型分类

  • 请求首部字段

  • 响应首部字段

  • 通用首部字段

  • 实体首部字段

    首部字段概述

  • 首部字段的作用:
    使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。

  • 首部字段的结构:
    HTTP首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔。

    首部字段名: 字段值
    

例如表示报文主体的对象类型:
Content-Type: text/html

- 字段值对应单个HTTP首部字段可以有多个值

Keep-Alive: timeout=15, max=100


>**若HTTP首部字段重复了会如何**。      当HTTP报文首部中出现了两个或两个以上具有相同首部字段名时会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。
## 请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于**补充请求的附加信息、客户端信息、对响应内容相关的优先级**等内容。    
| 请求首部字段 |  说明 |
|------|------------|
|Accept|`text/html,image/jpeg,video/mpeg,application/octet-stream`客户端可以接收的媒体类型(文本文件,图片文件,视频文件,二进制文件)|
|Accept-Charset|`iso-8859-5,unicode-1-1;q=0.8`能正确接收的字符集|
|Accept-Encoding|客户端能支持的内容编码(可多个):`gzip,compress,deflate`|
|Accept-Language|`zh-cn,zh;q=0.7,en-us,en;q=0.3`客户端能够处理的语言|
|Authorization|认证信息。当出现401时将其添加到请求头中便可认证|
|Expect|期待服务端的指定行为|
|From|告知服务器使用用户代理的用户的电子邮件地址。(使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式)|
|Host|(必须存在于请求头中) 告知服务器,请求的资源所处的互联网主机名和端口号`(当一个服务器下部署着多个域名的时候需指定,不然分不清请求的是哪一个域名)`|
|If-Match|形如if-xxx的格式,称为`条件请求`。服务器接收到条件后,只有判断指定条件为真,才会接受请求|
|If-Modified-Since|告知服务器若`If-Modified-Since`字段值早于资源的更新时间,则希望能处理该请求。而在指定`If-Modified-Since`字段值的日期时间之后,如果请求的资源都没有过更新,则返回状态码`304 Not Modified`的响应。|
|If-None-Match|资源未修改返回 304(通过对比ETag)|
|If-Range|告知服务器若指定的If-Range字段值(ETag值或者时间)和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。|
|If-Unmodified-Since|首部字段If-Unmodified-Since和首部字段If-Modified-Since的作用相反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码412 Precondition Failed作为响应返回。|
|Max-Forwards|限制可被代理及网关转发的次数|
|Proxy-Authorization|向代理服务器发送验证信息`(这个行为是与客户端和服务器之间的HTTP访问认证相类似的,不同之处在于,认证行为发生在客户端与代理之间。客户端与服务器之间的认证,使用首部字段Authorization可起到相同作用。)`|
|Range|`bytes=5001-10000`请求某个内容的一部分,配合If-Range使用|
|Referer|告知服务器请求的原始资源的URI。`(客户端一般都会发送Referer首部字段给服务器。但当直接在浏览器的地址栏输入URI,或出于安全性的考虑时,也可以不发送该首部字段。因为原始资源的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则有可能导致保密信息的泄露。)`|
|TE|`gzip,deflate;q=0.5.`告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段Accept-Encoding的功能很相像,但是用于传输编码。|
|User-Agent|将发起请求的**浏览器和用户代理名称等**信息**传达给服务器。|
## 响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于**补充响应的附加信息、服务器信息,以及对客户端的附加要求**等信息。

|响应首部字段|说明|
|------|------------|
|Accept-Ranges|告知客户端自己能否处理范围请求。能`bytes`,否`none`|
|Age|告知客户端,**源服务器**在多久前创建了响应。  若创建该响应的服务器是**缓存服务器**,Age值是指缓存后的响应再次发起认证到认证完成的时间值。`(资源在代理缓存中存在的时间)`|
| ETag|资源标识,资源发生变化时标识也会发生改变|
|Location|使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。基本上,该字段会配合3xx:Redirection的响应,提供重定向的URI。几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。|
|Proxy-Authenticate|把由代理服务器所要求的认证信息发送给客户端。|
|Retry-After|告知客户端应该在多久之后再次发送请求。主要配合状态码`503 Service Unavailable`响应|
|Server|`Apache/2.2.6 (Unix) PHP/5.2.5`告知客户端当前服务器上安装的HTTP服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。|
|Vary|对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。|
|WWW-Authenticate|用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic或是Digest)和带参数提示的质询(challenge)。状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate。|
## 通用首部字段
通用首部字段是指,请求报文和响应报文双方都会使用的首部。
| 通用首部字段 |  说明(请求报文和响应报文都会用到) |
|------|------------|
| Cache-Control|表示是否能缓存的指令。` public`(客户端、代理服务器都可利用缓存),`no-cache`(防止从缓存中返回过期的资源),`no-store`(暗示包含机密信息,不允许缓存),`s-maxage,max-age`(资源可缓存最大时间 秒)|
|Connection|`不再转发的首部字段名`(控制不再转发给代理的首部字段),`close`(关闭持续连接),`Keep-Alive`(在HTTP/1.0上开启持续连接,1.1默认持续连接所以不需要)|
|Data|表明创建HTTP报文的日期和时间|
|Pragma|`no-cache`(只用于请求报文,客户端要求中间服务器不返回缓存的资源)|
|Trailer|事先说明在报文主体后记录了哪些首部字段|
|Transfer-Encoding|`chunked`(规定了传输报文主体时采用的编码方式。)|
|Upgrade|检测HTTP协议及其他协议是否可使用更高的版本进行通信|
|Via|追踪客户端与服务器之间的请求和响应报文的传输路径。报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。首部字段Via不仅用于追踪报文的转发,还可避免请求回环的发生。所以必须在经过代理时附加该首部字段内容。|
|Warning|告知用户一些与缓存相关的问题的警告。|




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

在请求和响应两方的HTTP报文中都含有与实体相关的首部字段。
|实体首部字段|说明|
|------|-----|
|Allow|`GET,HEAD`。通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。|
|Content-Encoding|`gzip,compress,deflate,identity`。告知客户端服务器对实体的主体部分选用的内容编码方式。`内容编码是指在不丢失实体信息的前提下所进行的压缩`。|
|Content-Language|告知客户端,实体主体使用的自然语言(指中文或英文等语言)|
|Content-Length|表明了实体主体部分的大小(单位是字节)|
|Content-Location|返回数据的备用地址|
|Content-MD5|首部字段Content-MD5是一串由MD5算法生成的值,其目的在于`检查报文主体在传输过程中是否保持完整,以及确认传输到达`。|
|Content-Range|`bytes 5001-10000/10000`。告知客户端作为响应返回的实体的哪个部分符合范围请求。|
|Content-Type|`application/json;charset=UTF-8`。说明了实体主体内对象的媒体类型。|
|Expires|缓存服务器在接收到含有首部字段Expires的响应后,表示可以缓存到指定日期,到达指定日期,缓存服务器会向源服务器请求更新资源;同时也会告知客户端|
|Last-Modified|指明资源最终修改的时间|

## 为Cookie服务的首部字段
管理服务器与客户端之间状态的Cookie,虽然没有被编入标准化HTTP/1.1的RFC2616中,但在Web网站方面得到了广泛的应用。

Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前存放的Cookie。

调用Cookie时,由于可校验Cookie的**有效期**,以及发送方的**域、路径、协议**等信息,所以正规发布的Cookie内的数据不会因来自其他Web站点和攻击者的攻击而泄露。

|为Cookie服务的首部字段|说明|
|-----|-----|
|Set-Cookie|`name`:赋予Cookie的名称和其值;`expires`:Cookie的有效期(若不指定则默认为浏览关闭前为止);`path`:将服务器上的文件目录作为Cookie的适用对象;`domain = 域名`:作为Cookie适用对象的域名;`secure`:仅在HTTPS安全通行时才会发送Cookie;`HttpOnly`:加以限制,使Cookie不能被JavaScript脚本访问|
|Cookie|`Cookie: status=enable`:首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。|

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

|其他首部字段|说明|
|-----|-----|
|X-Frame-Options|`DENY(拒绝);SAMEORIGIN(仅同源域名下许可)`:用于控制网站内容在其他Web网站的Frame标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。|
|X-XSS-Protection|`0:将XSS过滤设置成无效状态`;`1 :将XSS过滤设置成有效状态`。它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器XSS防护机制的开关。|
|DNT|`0 :同意被追踪; 1 :拒绝被追踪`:DNT是Do NotTrack的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。由于首部字段DNT的功能具备有效性,所以Web服务器需要对DNT做对应的支持。|
|P3P|通过利用P3P(ThePlatform for Privacy Preferences,在线隐私偏好平台)技术,可以让Web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。|

>要进行P3P的设定,需按以下操作步骤进行。    
步骤1: 创建P3P隐私             
步骤2: 创建P3P隐私对照文件后,保存命名在/w3c/p3p.xml  
步骤3: 从P3P隐私中新建Compact policies后,输出到HTTP响应中



> **下一篇讲HTTPS,HTTP追加协议,WEB安全的知识点**

 上一篇
HTTPS,HTTP追加协议 - 重学计算机网络系列(4) HTTPS,HTTP追加协议 - 重学计算机网络系列(4)
本篇文章主要讲HTTPS,HTTP和HTTPS区别,认证,SPDY的AJAX与Comet,Websocket
2020-01-08
下一篇 
应用层 - 重学计算机网络系列(2) 应用层 - 重学计算机网络系列(2)
每个应用层协议都是为了解决某一类应用问题,而问题的解决又必须通过位于不同主机中的多个应用进程之间的通信和协同工作来完成。应用层的具体内容就是精确定义这些通信规则。
2020-01-08
  目录