HTTP——

文章目录

HTTP

请求报文的构成

如下图:
在这里插入图片描述
第一行:HTTP请求的方法,具体是POST方法还是GET方法,或是其它方法;URI就是你的HTTP请求的路径;后面是HTTP协议的版本;
第二行往下连续多行:这些是请求头部分,也就是请求的首部设置的一些信息,相当于对HTTP请求的一些设置;
空格行:在请求头与HTTP传递的内容实体之间,需要有一行空格;
空格行下方:空格行下方的内容是HTTP的内容实体,比如说客户端发送HTTP请求的时候所发送的参数;

响应报文的构成

如下图:
在这里插入图片描述
第一行:HTTP/1.1表示的是使用的HTTP协议的版本;200表示的是对客户端请求处理之后的结果对应的状态码;OK表示的是返回这个状态码的原因;
第二行以及下面的连续多行:这些行是HTTP响应头,也就是HTTP响应返回的首部信息,HTTP响应头部信息会提供给我们一些全局信息;
第三部分:在HTTP响应头和HTTP响应主体之间会有一行空格;
第四部分是响应主体:空格行后面的就是HTTP响应的内容主体了;

HTTP是不保存状态的协议

HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。如下图:
在这里插入图片描述
使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。

可是,随着Web的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其它页面后,也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。

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

请求URI定位资源

HTTP协议使用URI定位互联网上的资源。正是因为URI的特定功能,在互联网上任意位置的资源都能访问到。
在这里插入图片描述
当客户端请求访问资源而发送请求时,URI需要被包含在请求报文内。而指定URI的方式却有很多,比如我们可以写URI的全路径,就是域名加请求路径,但是也可以把域名和请求路径分开写在请求报文中,如下图:
在这里插入图片描述

除此之外,如果不是访问特定资源而是对服务器本身发起请求,可以用一个 星号 来代替请求URI。下面这个例子是查询HTTP服务器端支持的HTTP方法种类,如下图:
在这里插入图片描述

HTTP方法都有哪些?

GET方法:获取资源,主要用来查询内容

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

POST方法:传输实体主体,主要用来修改内容

POST方法用来传输实体的主体。虽然用GET方法也可以传输实体的主体,但一般不用GET方法进行传输,而是用POST方法。虽说POST的功能与GET很相似,但POST的主要目的并不是获取响应的主体内容。
在这里插入图片描述
在这里插入图片描述

PUT方法:传输文件,主要是用来增加的

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

但是鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的Web网站不使用该方法。若配合Web应用程序的验证机制,或架构设计采用REST(REpresentational State Transfer,表征状态转移)标准的同类Web网站,就可能会开放使用PUT方法。
在这里插入图片描述
在这里插入图片描述

DELETE方法:删除文件,主要是用来删除的

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

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

HEAD方法:获取报文的首部信息,也就是获取报文头

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

OPTIONS方法:询问支持的方法

OPTIONS方法用来查询针对请求URI指定的资源支持的方法,如下图:
在这里插入图片描述
在这里插入图片描述

使用HTTP持久连接节省通信量

HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。如下图:
在这里插入图片描述
中间只能进行一次HTTP请求和响应。进行一次HTTP请求和响应之后,就会断开TCP连接,那么下次HTTP请求仍需要重新建立TCP连接。

以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使这样也没有多大问题。可随着HTTP的普及,文档中包含大量图片的情况多了起来。

比如,使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问HTML页面资源的同时,也会请求该HTML页面里包含的其它资源。因此,每次的请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。如下图:
在这里插入图片描述
持久连接
为解决上述TCP连接的问题,HTTP/1.1和一部分的HTTP/1.0想出了持久连接(HTTP Persistent Connections,也称为HTTP keep-alive或HTTP connection reuse)的方法,其中reuse的意思是再用的意思。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。如下图:
在这里插入图片描述
持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使HTTP请求和响应能够更早地结束,这样Web页面的显示速度也就相应提高了。

在HTTP/1.1中,所有的连接默认都是持久连接,但在HTTP/1.0内并未标准化。虽然有一部分服务器通过非标准的手段实现了持久连接,但服务器端不一定能够支持持久连接。同理,客户端也不一定支持持久连接。

管线化

持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应也可直接发送下一个请求。

这样就能够做到同时并行发送多个请求了,而不需要一个接一个地等待响应了。
在这里插入图片描述
比如,当请求一个包含10张图片的HTML Web页面,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。

使用Cookie的状态管理

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

假设要求登录认证的Web页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面不是要再次登录,就是要在每次请求报文中附加参数来管理登录状态。

不可否认,无状态协议当然也有它的优点。由于不必保存状态,自然可减少服务器的CPU及内存资源的消耗。从另一侧面来说,也正是因为HTTP协议本身是非常简单的,所以才会被应用在各种场景里。
在这里插入图片描述
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了Cookie技术。Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。

Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。

服务器端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
在这里插入图片描述
在这里插入图片描述
上图展示了发生Cookie交互的情景,HTTP请求报文和响应报文的内容如下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我的初版理解:因为HTTP协议是无状态的,那么假如现在服务器想要访问一个客户端程序的A页面,必定需要先登录这个程序,所以服务端需要先给客户端发送一个HTTP登录请求;登录成功之后,假如服务器想要访问程序的B页面,这个时候因为HTTP是无状态的,所以客户端并不知道刚才服务端已经登录过一次了,因为客户端没有状态保存,所以这个时候如果服务端想要访问程序的B页面,首先必须重新登录一次,这样是不是显得非常不合理非常麻烦;因此为了解决HTTP协议是无状态的而导致需要重新登录的问题,就引入了Cookie技术;
当客户端第一次访问服务端的时候,服务端内部生成一个代表自己的Cookie,然后随着响应报文发给客户端。紧接着客户端保存这个服务端传递过来的Cookie,就代表是服务端的唯一标识了。那么等到下一次服务端访问客户端的时候,服务端会带上它的Cookie值,客户端内部接收到HTTP请求报文之后,会把服务端的Cookie和它内部存储的Cookie列表进行一次对比,如果客户端发现服务端传递过来的Cookie它已经有了,那么表示服务端在最近的时间内刚刚登录过,所以当服务端再次访问程序的B页面的时候就不用重新登录了。

利用MIME发送多种数据的多部分对象集合

在这里插入图片描述
发送邮件时,我们可以在邮件里写入文字并添加多份附件。这是因为采用了MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展)机制,它允许邮件处理文本、图片视频等多个不同类型的数据。例如,图片等二进制数据以ASCII码字符串编码的方式指明,就是利用MIME来描述标记数据类型。而在MIME扩展中会使用一种称为多部分对象集合(Multipart)的方法,来容纳多份不同类型的数据。

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

多部分对象集合包含的对象如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-type。

使用boundary字符串来划分多部分对象集合指明的各类实体。在boundary字符串指定的各个实体的起始行之前插入“–”标记(例如:–AaB03x、–THIS_STRING_SEPARATES),而在多部分对象集合对应的字符串的最后插入“–”标记(例如:–AaB03x–、–THIS_STRING_SEPARATES–)作为结束。

多部分对象集合的每个部分类型中,都可以含有首部字段。另外,可以在某个部分中嵌套使用多部分对象集合。

获取部分内容的范围请求

以前,用户不能使用现在这种高速的带宽访问互联网,当时,下载一个尺寸稍大的图片或文件就已经很吃力了。如果下载过程中遇到网络中断的情况,那就必须重头开始。为了解决上述问题,需要一种可恢复的机制。所谓恢复是指能从之前下载中断处恢复下载。

要实现该功能需要指定下载的实体范围。像这样,指定范围发送的请求叫做范围请求(Range Request)。

对一份10000字节大小的资源,如果使用范围请求,可以只请求5001~10000字节内的资源。如下图:
在这里插入图片描述
执行范围请求时,会用到首部字段Range来指定资源的byte范围。byte范围的指定形式如下:
在这里插入图片描述
在这里插入图片描述
针对范围请求,响应会返回状态码为206 Partial Content的响应报文。另外,对于多重范围的范围请求,响应会在首部字段Content-Type标明multipart/byteranges后返回响应报文。

如果服务器端无法响应范围请求,则会返回状态码200 OK和完整的实体内容。

状态码告知从服务器端返回的请求结果

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果的。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。如下图:
在这里插入图片描述
状态码200 OK,以3位数字和原因短语组成。
数字钟的第一位指定了响应类别,后两位无分类。响应类别有以下5种。如下图:
在这里插入图片描述
只要遵守状态码类别的定义,即使改变RFC2616中定义的状态码,或服务器端自行创建状态码都没问题。

2XX成功

2XX的响应结果标明请求被正常处理了。

200OK

如下图:
在这里插入图片描述
表示从客户端发来的请求在服务器端被正常处理了。

在响应报文内,随状态码一起返回的信息会因为方法的不同而发生改变。比如,使用GET方法时,对应请求资源的实体会作为响应返回;而使用HEAD方法时,对应请求资源的实体首部不随报文主体作为响应返回(即在响应中只返回首部,不会返回实体的主体部分)。

204 No Content

如下图:
在这里插入图片描述
该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如,当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新。

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

206 Partial Content

如下图:
在这里插入图片描述
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。

404 Not Found

如下图:
在这里插入图片描述
服务器上没有对应的资源。

500 Internal Server Error

如下图:
在这里插入图片描述
该状态码表明服务器端在执行请求时发生了错误。也可能是Web应用存在的bug或某些临时的故障。

通信数据转发程序:代理、网关、隧道

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

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

代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。

网关
网关是转发其它服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。

隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。

代理

如下图:
在这里插入图片描述
代理服务器的基本行为就是接收客户端发送的请求后转发给其它服务器。代理不改变请求URI,会直接发送给前方持有资源的目标服务器。

持有资源实体的服务器被称为源服务器。从原服务器返回的响应经过代理服务器后再传给客户端。如下图:
在这里插入图片描述
在HTTP通信过程中,可级联多台代理服务器。请求和响应的转发会经过数台类似锁链一样连接起来的代理服务器。转发时,需要附加Via首部字段以标记出经过的主机信息。
在这里插入图片描述
使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的,等等。

代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。

缓存代理
代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。

当代理再次接收到对相同资源的请求时,就可以不从源服务器哪里获取资源,而是将之前缓存的资源作为响应返回。

透明代理
转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。

网关

在这里插入图片描述
网关的工作机制和代理十分相似。而网关能够使通信线路上的服务器提供非HTTP协议服务。

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

隧道

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

隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。如下图:
在这里插入图片描述

保存资源的缓存

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

缓存服务器是代理服务器的一种,并归类在缓存代理类型中。换句话说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。如下图:
在这里插入图片描述
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处理相同的请求了。

缓存的有效期限

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

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

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

客户端的缓存

缓存不仅可以存在于缓存服务期内,还可以存在客户端浏览器中。以Internet Explorer程序为例,把客户端缓存称为临时网络文件(Temporary Internet File)。

浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。

另外,和缓存服务器相同的一点是,当判定缓存过期后,会向源服务器确认资源的有效性。若判断浏览器缓存失效,浏览器会再次请求新资源。
在这里插入图片描述

HTTP首部

HTTP协议的请求和响应报文中必定包含HTTP首部,只是我们平时在使用Web的过程中感受不到它。

HTTP报文首部

如下图:
在这里插入图片描述
HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。对于客户端用户来说,这些信息中的大部分内容都无须亲自查看。
报文首部由几个字段构成。

HTTP请求报文
在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。如下图:
在这里插入图片描述
下面的示例是访问http://hackr.jp时,请求报文的首部信息。
在这里插入图片描述
在这里插入图片描述
HTTP响应报文
在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。如下图:
在这里插入图片描述
以下示例是之前请求访问http://hackr.jp/时,返回的响应报文的首部信息。如下图:
在这里插入图片描述
在报文众多的字段当中,HTTP首部字段包含的信息最为丰富。首部字段同时存在于请求和响应报文内,并涵盖HTTP报文相关的内容信息。

因HTTP版本或扩展规范的变化,首部字段可支持的字段内容略有不同。我们这里主要是讲解的HTTP/1.1及常用的首部字段。

HTTP首部字段传递重要信息

HTTP首部字段是构成HTTP报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。

使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
在这里插入图片描述

HTTP首部字段结构

HTTP首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔。如下图:
在这里插入图片描述
例如,在HTTP首部中以Content-Type这个字段来表示报文主体对象类型。如下图:
在这里插入图片描述
就以上述示例来看,首部字段名为Content-Type,字符串text/html是字段值。

另外,字段值对应单个HTTP首部字段可以有多个值,如下图所示:
在这里插入图片描述
若HTTP首部字段重复了会如何
当HTTP报文首部中出现了两个或两个以上具有相同首部字段名时会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。

4种HTTP首部字段类型

HTTP首部字段根据实际用途被分为以下4种类型。

  • 通用首部字段(General Header Fields)。请求报文和响应报文两方都会使用首部。
  • 请求首部字段(Request Header Fields)。从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
  • 响应首部字段(Response Header Fields)。从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
  • 实体首部字段(Entity Header Fields)。针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

HTTP/1.1首部字段一览

HTTP/1.1规范定义了如下47种首部字段。如下图:
通用首部字段
在这里插入图片描述

请求首部字段
在这里插入图片描述
在这里插入图片描述
响应首部字段
在这里插入图片描述
在这里插入图片描述

实体首部字段
在这里插入图片描述

非HTTP/1.1首部字段

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

这些非正式的首部字段统一归纳在RFC4229 HTTP 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个首部字段之外,其它所有字段都属于端到端首部。
在这里插入图片描述

HTTP/1.1通用首部字段

通用首部字段是指,请求报文和响应报文双方都会使用的首部。

Cache-Control

通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。如下图:
在这里插入图片描述
指令的参数是可选的,多个指令之间通过“,”分隔。首部字段Cache-Control的指令可用于请求及响应时,如下图:
在这里插入图片描述
Cache-Control指令一览
可用的指令按请求和响应分类如下所示,首先看一下请求指令,如下图:
在这里插入图片描述
在这里插入图片描述
接下来再来看下缓存响应指令,如下图:
在这里插入图片描述
private指令
在这里插入图片描述
当指定private指令后,响应只以特定的用户作为对象,这与public指令的行为相反。

缓存服务器会对该特定用户提供资源缓存的服务,对于其它用户发送过来的请求,代理服务器则不会返回缓存。

no-cache指令
在这里插入图片描述
使用no-cache指令的目的是为了防止从缓存中返回过期的资源。
客户端发送的请求中如果包含no-cache指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存服务器必须把客户端请求转发给源服务器。

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

no-store指令
如下图:
在这里插入图片描述
当使用no-store指令时,暗示请求(和对应的响应)或响应中包含机密信息。
因此,该指令规定缓存不能在本地存储请求或响应的任一部分。

max-age指令
如下图:
在这里插入图片描述
当客户端发送的请求中包含max-age指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。另外,当指定max-age值为0,那么缓存服务器通常需要将请求转发给源服务器。

当服务器返回的响应中包含max-age指令时,缓存服务器将不对资源的有效性再作确认,而max-age数值代表资源保存为缓存的最长时间。

应用HTTP/1.1版本的缓存服务器遇到同时存在Expires首部字段的情况时,会优先处理max-age指令,而忽略掉Expires首部字段。而HTTP/1.0版本的缓存服务器的情况却相反,max-age指令会被忽略掉。

s-maxage指令
在这里插入图片描述
s-maxage指令的功能和max-age指令相同,它们的不同点是s-maxage指令只适用于供多位用户使用的公共缓存服务器。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。

另外,当使用s-maxage指令后,则直接忽略对Expires首部字段及max-age指令的处理。

min-fresh指令
如下图:
在这里插入图片描述
min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源。
比如,当指定min-fresh为60秒后,过了60秒的资源都无法作为响应返回了。

max-stale指令
在这里插入图片描述
使用max-stale可指示缓存资源,即使过期也照常接收。

如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。

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

must-revalidate指令
如下图:
在这里插入图片描述
使用must-revalidate指令,代理会向源服务器再次获取有效资源的话,缓存必须给客户端一条504(Gateway Timeout)状态码。

另外,使用must-revalidate指令会忽略请求的max-stale指令(即使已经在首部使用了max-stale,也不会再有效果)。

proxy-revalidate指令
如下图:
在这里插入图片描述
proxy-revalidate指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。

no-transform指令
如下图:
在这里插入图片描述
使用no-transform指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。

这样做可防止缓存或代理压缩图片等类似操作。

Connextion

Connection首部字段具备如下两个作用。

  • 控制不再转发给代理的首部字段。
  • 管理持久连接。

首先看下是怎么控制不再转发给代理的首部字段的,如下图:
在这里插入图片描述
在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段(即Hop-by-hop首部)。

接着再来看下如何管理持久连接,如下图:
在这里插入图片描述
HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close。
在这里插入图片描述
HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。
如上图①所示,客户端发送请求给服务器时,服务器端会像上图②那样加上首部字段Keep-Alive及首部字段Connection后返回响应。

Date

首部字段Date标明创建HTTP报文的日期和时间,如下图:
在这里插入图片描述
HTTP/1.1协议使用在RFC1123中规定的日期时间的格式,如下图:
在这里插入图片描述
之前的HTTP协议版本中使用在RFC850中定义的格式,如下图:
在这里插入图片描述
除此之外,还有一种格式。它与C标准库内的asctime()函数的输出格式一致,如下图:
在这里插入图片描述

Pragma

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

规范定义的形式唯一,如下图所示:
在这里插入图片描述
该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。
在这里插入图片描述
所有的中间服务器如果都能以HTTP/1.1为基准,那直接采用Cache-Control:no cache指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的HTTP协议版本却是不现实的。因此,发送的请求会同时含有下面两个首部字段。如下图:
在这里插入图片描述

Trailer

如下图:
在这里插入图片描述
首部字段Trailer会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在HTTP/1.1版本分块传输编码时,如下图:
在这里插入图片描述
在这里插入图片描述
以上用例中,指定首部字段Trailer的值为Expires,在报文主体之后(分块长度0之后)出现了首部字段Expires。

Transfer-Encoding
如下图:
在这里插入图片描述
首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。
HTTP/1.1的传输编码方式仅对分块传输编码有效。
在这里插入图片描述
在这里插入图片描述
以上用例中,正如在首部字段Transfer-Encoding中指定的那样,有效使用分块传输编码,且分别被分成3312字节和914字节大小的分块数据。

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

Via

使用首部字段Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径。
报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。这个做法和traceroute及电子邮件的Received首部的工作机制很类似。

首部字段Via不仅用于追踪报文的转发,还可以避免请求回环的发生。所以必须在经过代理时附加该首部字段内容。如下图:
在这里插入图片描述
上图用例中,在经过代理服务器A时,Via首部附加了“1.0 gw.hackr.jp(Squid/3.1)”这样的字符串值。行头的1.0是指接收请求的服务器上应用的HTTP协议版本。接下来经过代理服务器B时也是如此,在Via首部附加服务器信息,也可增加1个新的Via首部写入服务器信息。

Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到由TRACE方法发送过来的请求(其中Max-Forwards:0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。

请求首部字段

请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。如下图:
在这里插入图片描述

Accept

在这里插入图片描述
Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型。
下面我们举几个媒体类型的例子,如下图:
在这里插入图片描述
比如,如果浏览器不支持PNG图片的显示,那Accept就不指定image/png,而指定可处理的image/gif和image/jpeg等图片类型。

若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,用分号(;)进行分隔。权重值q的方位是0~1(可精确到小数点后3位),且1位最大值。不指定权重q值时,默认权重为q=1.0

当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。

Accept-Charset

如下图:
在这里插入图片描述
Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段Accept相同的是可用权重q值来表示相对优先级。

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

Accept-Encoding

如下图:
在这里插入图片描述
Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
下面举几个内容编码的例子,如下图:
在这里插入图片描述
采用权重q值来表示相对优先级,这点与首部字段Accept相同。另外,也可使用星号(*)作为通配符,指定任意的编码格式。

Accept-Language

如下图:
在这里插入图片描述
首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次性指定多种自然语言集。

和Accept首部字段一样,按权重值q来表示相对优先级。在上述图例中,客户端在服务器有中文版资源的情况下,会请求其返回中文版对应的响应,没有中文版时,则请求返回英文版响应。

Authorization

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

From

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

Host

如下图:
在这里插入图片描述
在这里插入图片描述
首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。

首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段Host必须存在的意义。

请求被发送至服务器时,请求中的主机名会用IP地址直接替换解决。但如果这时,相同的IP地址下部署运行着多个域名,那么服务器就会无法理解究竟是哪个域名对应的请求。因此,就需要使用首部字段Host来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。如下:
在这里插入图片描述

If-Match

如下图:
在这里插入图片描述
形如If-xxx这种样式的请求首部字段,都可成为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。如下图:
在这里插入图片描述
在这里插入图片描述
首部字段If-Match,属附带条件之一,它会告知服务器匹配资源所用的实体标记(ETag)值。这时的服务器无法使用弱ETag值。

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

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

If-Modified-Since

如下图:
在这里插入图片描述
在这里插入图片描述
首部字段If-Modified-Since,属附带条件之一,它会告知服务器若If-Modified-Since字段值早于资源的更新时间,则希望能处理该请求。而在指定If-Modified-Since字段值的日期时间之后,如果请求的资源都没有过更新,则返回状态码304 Not Modified的响应。

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

If-None-Match

如下图:
在这里插入图片描述
首部字段If-None-Match属于附带条件之一。它和首部字段If-Match作用相反。用于指定If-None-Match字段值的实体标记(ETag)值与请求资源的ETag不一致时,它就告知服务器处理该请求。

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

If-Unmodified-Since

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

Max-Forwards

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

使用HTTP协议通信时,请求可能会经过代理等多台服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器返回的响应了。对此,我们无从可知。

可以灵活使用首部字段Max-Forwards,针对以上问题产生的原因展开调查。由于当Max-Forwards字段值为0时,服务器就会立即返回响应,由此我们至少可以对以那台服务器未终点的传输路径的通信状况有所把握。
在这里插入图片描述

Range

在这里插入图片描述
对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。上面的示例表示请求获取从第5001字节到第10000字节的资源。

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

Referer

在这里插入图片描述
首部字段Referer会告知服务器请求的原始资源的URI。客户端一般都会发送Referer首部字段给服务器。但当直接在浏览器的地址栏输入URI,或出于安全性的考虑时,也可以不发送该首部字段。

因为原始资源的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发给其它服务器,则有可能导致保密信息的泄漏。

另外,Referer的正确的拼写应该是Referrer,但不知为何,大家一直沿用这个错误的拼写。

User-Agent

在这里插入图片描述
首部字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。

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

响应首部字段

响应首部字段是由服务器端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息。以及对客户端的附加要求等信息。
在这里插入图片描述

Accept-Ranges

在这里插入图片描述
首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。

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

Age

在这里插入图片描述
首部字段Age能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。

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

ETag

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

另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。
在这里插入图片描述
资源被缓存时,就会被分配唯一的标识。例如,当使用中文版的浏览器访问http://www.google.com/时,就会返回中文版对应的资源,而使用英文版的浏览器访问时,则会返回英文版对应的资源。两者的URI是相同的,所以仅凭URI指定缓存的资源是相当困难的。若在下载过程中出现连接中断、再连接的情况,都会依照ETag值来指定资源。

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

强ETag值
强ETag值,不论实体发生多么细微的变化都会改变其值。
在这里插入图片描述
弱ETag值
弱ETag值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/。
在这里插入图片描述

Location

在这里插入图片描述
在这里插入图片描述
使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。

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

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

Retry-After

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

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

Server

在这里插入图片描述
首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。
在这里插入图片描述

Vary

在这里插入图片描述在这里插入图片描述

实体首部字段

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

Allow

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

Content-Encoding

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

Content-Language

在这里插入图片描述
首部字段Content-Language会告知客户端,实体主体使用的自然语言(指中文或英文等语言)。

Content-Length

在这里插入图片描述
首部字段Content-Length表明了实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。

Content-Location

在这里插入图片描述
首部字段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说明了实体主体内对象的媒体类型。

Expires

在这里插入图片描述
首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。

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

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

Last-Modified

在这里插入图片描述
首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。

为Cookie服务的首部字段

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

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

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

到2013年5月,Cookie的规格标准文档有以下4种:
在这里插入图片描述
目前使用最广泛的Cookie标准却不是RFC中定义的任何一个。而是在网景公司制定的标准上进行扩展后的产物。
下面的表格内列举了与Cookie有关的首部字段,如下图:
在这里插入图片描述

Set-Cookie

在这里插入图片描述
当服务器准备开始管理客户端的状态时,会事先告知各种信息。下面的表格列举了Set-Cookie的字段值,如下图:
在这里插入图片描述
在这里插入图片描述

expires属性
Cookie的expires属性指定浏览器可发送Cookie的有效期。
当省略expires属性时,其有效期仅限于维持浏览器会话(Session)时间段内。这通常限于浏览器应用程序被关闭之前。

另外,一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显式删除Cookie的方法。但可通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。

path属性
Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。不过另有办法可避开这项限制,看来对其作为安全机制的效果不能抱有期待。

domain属性
通过Cookie的domain属性指定的域名可做到与结尾匹配一致。比如,当指定example.com后,除example.com以外,www.example.com或www2.example.com等都可以发送Cookie。

因此,除了针对具体指定的卭域名发送Cookie之外,不指定domain属性显得更安全。

secure属性
Cookie的secure属性用于限制Web页面仅在HTTPS安全连接时才可以发送Cookie。

发送Cookie时,指定secure属性的方法如下所示:
在这里插入图片描述
以上例子仅当在https://www.example.com/ (HTTPS)安全连接的情况下才会进行Cookie的回收。也就是说即使域名相同,http://www.example.com/ (HTTP)也不会发生Cookie回收行为。

当省略secure属性时,不论HTTP还是HTTPS,都会对Cookie进行回收。

HttpOnly属性

Cookie的HttpOnly属性是Cookie的扩展功能,它使JavaScript脚本无法获得Cookie。其主要目的是为了防止跨站脚本攻击(Cross-site sccripting, XSS)对Cookie的信息窃取。

发送指定HttpOnly属性的Cookie的方法如下所示:
在这里插入图片描述
通过上述设置,通常从Web页面内还可以对Cookie进行读取操作。但是用JavaScript的document.cookie就无法读取附加HttpOnly属性后的Cookie的内容了。因此,也就无法在XSS中利用JavaScript劫持Cookie了。

虽然是独立的扩展功能,但Internet Explorer 6 SP1以上版本等当下的主流浏览器都已经支持该扩展了。另外顺带一提,该扩展并非是为了防止XSS而开发的。

Cookie

在这里插入图片描述
首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。

确保Web安全的HTTPS

在HTTP协议中有可能存在信息窃听或身份伪装等安全问题。使用HTTPS通信机制可以有效地防止这些问题。

HTTP的缺点

到现在为止,我们已了解到HTTP具有相当优秀和方便的一面,然而HTTP并非只有好的一面,事物皆具有两面性,它也是有不足之处的。
在这里插入图片描述
这些问题不仅在HTTP上出现,其他未加密的协议中也会存在这类问题。

除此之外,HTTP本身还有很多缺点。而且,还有像某些特定Web服务器和特定的Web浏览器在实际应用中存在的不足(也可以说成是脆弱性或安全漏洞),另外,用Java和PHP等编程语言开发的Web应用也可能存在安全漏洞。

通信使用明文可能会被窃听
由于HTTP本身不具备加密的功能,所以也无法做到对通信整体(使用HTTP协议通信的请求和响应的内容)进行加密。即,HTTP报文使用明文(指未经过加密的报文)方式发送。

TCP/IP是可能被窃听的网络
如果要问为什么通信时不加密是一个缺点,这是因为,按TCP/IP协议族的工作机制,通信内容在所有的通信线路上都有可能早到窥视。

所谓互联网,是由能联通到全世界的网络组成的。无论世界哪个及哦啊罗的服务器在和客户端通信时,在此通信线路上的某些网络设备、光缆、计算机等都不可能是个人的私有物,所以不排除某个环节中会遭到恶意窥视行为。

即使已经加密处理过的通信,也会被窥视到通信内容,这点和未加密的通信时相同的。只是说如果通信经过加密,就有可能让人无法破解报文信息的含义,但加密处理后的报文信息本身还是会被看到的。
在这里插入图片描述
窃听相同段上的通信并非难事。只需要收集在互联网上流动的数据包(帧)就行了。对于收集来的数据包的解析工作,可交给那些专业的抓包工具,比如说Fiddle,和WireShark(这个我的电脑无法安装),所以我最后安装的是Fiddle。

加密处理防止被窃听
在目前大家正在研究的如何防止窃听保护信息的几种对策中,最为普及的就是加密技术。加密的对象可以有这么几个。

通信的加密
一种方式就是将通信加密。HTTP协议中没有加密机制,但是可以通过和SSL(Secure Socket Layer,安全套接层)或TLS(Transport Layer Security,安全层传输协议)的组合使用,加密HTTP的通信内容。

用SSL建立安全通信线路之后,就可以在这条线路上进行HTTP通信了。与SSL组合使用的HTTP被称为HTTPS(HTTP Secure,超文本传输安全协议)或 HTTP over SSL。
在这里插入图片描述

内容的加密
还有一种将参与通信的内容本身加密的方式。由于HTTP协议中没有加密机制,那么就对HTTP协议传输的内容本身加密。即把HTTP报文里所含的内容进行加密处理。

在这种情况下,客户端需要对HTTP报文进行加密处理后再发送请求。
在这里插入图片描述
诚然,为了做到有效的内容加密,前提是要求客户端和服务器同时具备加密和解密机制。主要应用在Web服务器中。有一点必须引起注意,由于该方式不同于SSL或TLS将整个通信线路加密处理,所以内容仍有被篡改的风险。

不验证通信方的身份就可能遭遇伪装

HTTP协议中的请求和响应不会对通信方进行确认。也就是说存在“服务器是否就是发送请求中URI真正指定的主机,返回的响应是否真的返回到实际提出请求的客户端”等类似问题。

任何人都可发起请求
在HTTP协议通信时,由于不存在确认通信方的处理步骤,任何人都可以发起请求。另外,服务器只要接收到请求,不管对方是谁都会返回一个响应(但也仅限于发送端的IP地址和端口号没有被Web服务器设定限制访问的前提下)。
在这里插入图片描述
HTTP协议的实现本身非常简单,不论是谁发送过来的请求都会返回响应,因此不确认通信方,会存在以下各种隐患。

  • 无法确定请求发送至目标的Web服务器是否是按真实意图返回响应的那台服务器。有可能是已伪装的Web服务器。
  • 无法确定响应返回到的客户端是否是按真实意图接收响应的那个客户端。有可能是已伪装的客户端。
  • 无法确定正在通信的对方是否具备访问权限。因为某些Web服务器上保存着重要的信息,只想发给特定用户通信的权限。
  • 无法判定请求是来自何方、出自谁手。
  • 即使是无意义的请求也会照单全收。无法阻止海量请求下的DoS攻击(Denial of Service,拒绝服务攻击)。

查明对手的证书
虽然使用HTTP协议无法确定通信方,但如果使用SSL则可以。SSL不仅提供加密处理,而且还使用了一种被称为证书的手段,可用于确定方。

证书由值得信任的第三方机构颁发,用以证明服务器和客户端是实际存在的。另外,伪造证书从技术角度来说是异常困难的一件事情。所以只要能够确认通信方(服务器或客户端)持有的证书,即可判断通信方的真实意图。
在这里插入图片描述
通过使用证书,以证明通信方就是意料中的服务器。这对使用者个人来讲,也减少了个人信息泄露的危险性。

另外,客户端持有证书即可完成个人身份的确认,也可用于对Web网站的认证环节。

无法证明报文完整性,可能已遭篡改

所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着无法判断信息是否准确。

接收到的内容可能有误
由于HTTP协议无法证明通信的报文完整性,因此,在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。

换句话说,没有任何办法确认,发出的请求/响应和接收到的请求/响应时前后相同的。
在这里插入图片描述
比如,从某个Web网站上下载内容,是无法确定客户端下载的文件和服务器上存放的文件是否前后一致的。文件内容在传输途中可能已经被篡改为其他的内容。即使内容真的已经改变,作为接收方的客户端也是觉察不到的。

像这样,请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击(Man-in-the-Middle attack, MITM)。
在这里插入图片描述
如何防止篡改
虽然有使用HTTP协议确定报文完整性的方法,但事实上并不便捷、可靠。其中常用的是MD5和SHA-1等散列值校验的方法,以及用来确认文件的数字签名方法。
在这里插入图片描述
提供文件下载服务的Web网站也会提供响应的以PGP(Pretty Good Privacy,完美隐私)创建的数字签名及MD5算法生成的散列值。PGP是用来证明创建文件的数字签名,MD5是由单向函数生成的散列值。不论使用哪一种方法,都需要操纵客户端的用户本人亲自检查验证下载的文件是否就是原来服务器上的文件。浏览器无法自动帮用户检查。

可惜的是,用这些方法也依然无法百分百保证确认结果正确。因为PGP和MD5本身被改写的话,用户是没有办法意识到的。

为了有效防止这些弊端,有必要使用HTTPS。SSL提供认证和加密处理以及摘要功能。仅靠HTTP确保完整性是非常困难的,因此通过和其它协议组合使用来实现这个目标。

HTTP + 加密 + 认证 + 完整性保护 = HTTPS

HTTP加上加密处理和认证以及完整性保护后即是HTTPS
如果在HTTP协议通信过程中使用未经加密的明文,比如在Web页面中输入信用卡号,如果这条通信线路遭到了窃听,那么信用卡号就暴露了。

另外,对于HTTP来说,服务器也好,客户端也好,都是没有办法确认通信方的。因为很有可能并不是和原本预想的通信方在实际通信。并且还需要考虑到接收到的报文在通信途中已经遭到篡改这一可能性。

为了统一解决上述这些问题,需要在HTTP上再加入加密处理和认证等机制。我们把添加了加密及认证机制的HTTP称为HTTPS(HTTP Secure)。
在这里插入图片描述
经常会在Web的登录页面和购物结算界面等使用HTTPS通信。使用HTTPS通信时,不再使用http://,而是改用https://。另外,当浏览器访问HTTPS通信有效的Web网站时,浏览器的地址栏内会出现一个带锁的标记。对HTTPS的显示方式会因浏览器的不同而有所改变。
在这里插入图片描述
HTTPS是身披SSL外壳的HTTP
HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL(Secure Socket Layer)和TLS(Transport Layer Security)协议代替而已。

通常,HTTP直接和TCP通信。当时用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简而言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。
在这里插入图片描述
在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。

SSL是独立于HTTP的协议,所以不光是HTTP协议,其它运行在应用层的SMTP和Telnet等协议均可配合SSL协议使用。可以说SSL是当今世界上应用最为广泛的网络安全技术。

相互交换密钥的公开密钥加密技术

在对SSL进行讲解之前,我们先来了解一下加密方法。SSL采用一种叫做公开密钥加密(Public-key cryptography)的加密处理方式。

近代的加密方法中加密算法是公开的,而密钥却是保密的。通过这种方式得以保持加密方法的安全性。

加密和解密都会用到密钥。没有密钥就无法对密码解密,反过来说,任何人只要持有密钥就能解密了。如果密钥被攻击者获得,那加密也就失去了意义。

共享密钥加密的困境
加密和解密同用一个密钥的方式称为共享密钥加密(Common key crypto system),也被叫做对称密钥加密。
在这里插入图片描述
以共享密钥方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通信被监听那么密钥就可能会落入攻击者之手,同时也就失去了加密的意义。另外还要设法安全地保管接收到的密钥。
在这里插入图片描述
使用两把密钥的公开密钥加密
公开密钥加密方式很好地解决了共享密钥加密的困难。
公开密钥加密使用一对非对称的密钥。一把叫做私有密钥(private key),另一把叫做公开密钥(public key)。顾明思义,私有密钥不能让其它任何人知道,而公开密钥则可以随意发布,任何人都可以获得。

使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。

另外,要想根据密文和公开密钥,恢复到信息原文是异常困难的,因为解密过程就是在对离散对数进行求值,这并非轻而易举就能办到的。退一步讲,如果能对一个非常大的整数做到快速地因式分解,那么密码破解还是存在希望的。但就目前的技术来看是不太现实的。
在这里插入图片描述

HTTPS采用混合加密机制
HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制。若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。

所以应充分利用两者各自的优势,将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。

在这里插入图片描述

证明公开密钥正确性的证书
遗憾的是,公开密钥加密方式还是存在一些问题的。那就是无法证明公开密钥本身就是货真价实的公开密钥。比如,正准备和某台服务器建立公开密钥加密方式下的通信时,如何证明收到的公开密钥就是原本预想的那台服务器发行的公开密钥。或许在公开密钥传输途中,真正的公开密钥已经被攻击者替换掉了。

为了解决上述问题,可以使用由数字证书认证机构(CA,Certificate Authority)和其相关颁发的公开密钥证书。

数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。威瑞信(VeriSign)就是其中一家非常有名的数字证书认证机构。我们来介绍一下数字证书认证机构的业务流程。首先,服务器的运营人员向数字证书认证机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。

服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。公钥证书也可佳作数字证书或直接称为证书。

接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。

此处认证机关的公开密钥必须安全地转交给客户端。使用通信方式时,如何安全转交是一件很困难的事,因此,多数浏览器开发商发布版本时,会实现在内部植入常用认证机关的公开密钥。

在这里插入图片描述
在这里插入图片描述

SSL和TLS

HTTPS使用SSL(Secure Socket Layer)和TLS(Transport Layer Security)这两个协议。

SSL技术最初是由浏览器开发商网景通信公司率先倡导的,开发过SSL3.0之前的版本。目前主导权已转移到IETF(Internet Engineering Task Force, Internet 工程任务组)的手中。

IETF以SSL3.0位基准,后又制定了TLS1.0、TLS1.1和TLS1.2。TSL
是以SSL为原型开发的协议,有时会统一称该协议为SSL。当前主流的版本是SSL3.0和TLS1.0

由于SSL1.0协议在设计之初被发现出了问题,就没有实际投入使用。SSL2.0也被发现存在问题,所以很多浏览器直接废除了该协议版本。

SSL速度慢吗?
HTTPS也存在一些问题,那就是当使用SSL时,它的处理速度会变慢。
在这里插入图片描述
SSL的慢分两种。一种是指通信慢。另一种是指由于大量消耗CPU及内存等资源,导致处理速度变慢。

和使用HTTP相比,网络负载可能会变慢2到100倍。除去和TCP连接、发送HTTP请求、响应以外,还必须进行SSL通信,因此整体上处理通信量不可避免会增加。

另一点是SSL必须进行加密处理。在服务器和客户端都需要进行加密和解密的运算处理。因此从结果上讲,比起HTTP会更多地消耗服务器和客户端的硬件资源,导致负载增强。

针对速度变慢这一问题,并没有根本性的解决方案,我们会使用SSL加速器这种(专用服务器)硬件来改善该问题。该硬件为SSL通信专用硬件,相对软件来讲,能够提高数倍SSL的计算速度。仅在SSL处理时发挥SSL加速器的功效,以分担负载。

为什么不一直使用HTTPS?
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr-X~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值