(转)《图解HTTP》第2-4章笔记

摘要

《图解HTTP》第2-4章笔记,特此记录重要部分。

第2章 简单的HTTP协议

2.3 HTTP是不保存状态的协议

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

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

HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。

2.5 告知服务器意图的HTTP方法

GET:获取资源

请求:

1
2
3
4
5
GET /index.html HTTP/1.1
Host:www.hackr.jp
If-Modified-Since:Thu,12 Jul 2012 07:30:00 GMT

响应:

仅返回2012年7月12日7点30分以后更新过的index.html页面资源。如果未有内容更新,则以状态码304 Not Modified作为响应返回

POST:传输实体主体

请求:

1
2
3
4
5
POST /submit.cgi HTTP/1.1
Host:www.hackr.jp
Content-Length:1560(1560字节的数据)

响应:

返回submit.cgi接收数据的处理结果

HEAD:获得报文首部

HEAD方法和GET方法一样,只是不返回报文主体部分。

PUT:传输文件 和 DELETE:删除文件

由于HTTP/1.1的DELETE方法和PUT方法都不带验证机制,所以一般的Web网络不使用这两个方法。

OPTIONS:询问支持的方法

请求:

1
2
3
OPTION * HTTP/1.1
Host:www.hackr.jp

响应:

1
2
3
HTTP/1.1 200 OK
ALLOW:GET,POST,HEAD,OPTIONS(返回服务器支持的方法)

2.7 持久连接节省通信量

HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。

但是随着HTTP的普及,使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问HTML页面资源的同时,也会请求该HTML页面里包含的其他资源。因此,每次的请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。

2.7.1 持久连接

为了解决上述TCP连接的问题,HTTP/1.1和一部分HTTP/1.0想出了持久连接(HTTP Persistent Connection,也称为HTTP keep-alive或HTTP connection reuse)的方法。

持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。

在HTTP/1.1中,所有的连接默认都是持久连接,但在HTTP/1.0内并未标准化。

2.7.2 管线化

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

这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。

2.8 使用Cookie的状态管理

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

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

服务器端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

1.请求报文

1
2
3
GET /reader/ HTTP/1.1
Host:hackr.jp

首部字段内没有Cookie的相关信息

2.响应报文

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK
Date:Thu, 12 Jul 2012 07:12:20 GMT
Server:Apache
<Set-Cookie: sid=1342077140226724;path=/; expires=Web,=>10-Oct-12 07:12:20 GMT>
Content-Type:text/plain;charset=UTF-8

3.请求报文

1
2
3
4
5
GET /image/ HTTP/1.1
Host:hackr.jp
Cookie:sid=1342077140226724

第3章 HTTP报文内的HTTP信息

3.3 编码提升传输速率

HTTP在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量的访问请求。但是编码的操作需要计算机来完成,因此会消耗更多的CPU等资源。

3.3.1 报文主体和实体主体的差异

1.报文

是HTTP通信中的基本单位,由8位组字节流组成,通过HTTP通信传输。

2.实体

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

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

3.3.2 压缩传输的内容编码

内容编码指明在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。

常见的内容编码有几种方式:1.gzip(GUN zip);2.compress(UNIX系统的标准压缩);3.deflate(zlib);4.identity(不进行编码)。

3.3.3 分割发送的分块传输编码

在HTTP通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。

这种把实体主体分块的功能称为分块传输编码。

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

3.4 发送多种数据的多部分对象集合

发送邮件时,我们可以在邮件里写入文字并添加多份附件。这是因为采用了MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展)机制,它允许邮件处理文本、图片、视频等多个不同类型的数据。

MIME扩展中会使用一种称为多部分对象集合(Multipart)的方法,来容纳多分不同类型的数据。

相应地,HTTP协议中也采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。

多部分对象集合包含的对象如下:

1.multipart/form-data

在Web表单文件上传时使用。

1
2
3
4
5
6
7
8
9
10
11
12
Content-Type:multipart/form-data;boundary=AaB03x
--AaB03x
Content-Disposition:form-data;name="file1"
Joe Blow
--AaB03x
Content-Disposition:form-data;name="pics";filename="file1.txt"
Content-Type:text/plain
...(file1.txt的数据)...
--AaB03x--

2.multipart/byteranges

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HTTP/1.1 206 Partial Content
Date:Fri,13 Jul 2012 02:45:26 GMT
Last-Modified:Fri,31 Aug 2007 02:02:30 GMT
Content-Type:multipart/byteranges;boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type:application/pdf
Content-Range:bytes 500-999/8000
...(范围指定的数据)...
--THIS_STRING_SEPARATES
Content-Type:application/pdf
Content-Range:bytes 7000-7999/8000
...(范围指定的数据)...
--THIS_STRING_SEPARATES--

在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-Type。

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

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

3.5 获取部分内容的范围请求(断点续传的应用)

执行范围请求时,会用到首部字段Range来指定支援的byte范围。

1.5001-10000字节

Range:byte=5001-10000

2.从5001字节之后全部的

Range:byte=5001-

3.从一开始到3000字节和5000-7000字节的多重范围

Range:byte=-3000,5000-7000

针对范围请求,响应会返回状态码为206 Partial Content的响应报文。

对应多重范围的范围请求,响应会在首部字段Content-Type标明multipart/byteranges后返回响应报文。

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

3.6 内容协商返回最合适的内容

内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为合适的资源。

内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准。

包含在请求报文中的某些首部字段就是判断的基准。

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Content-Language

内容协商技术有以下3种类型:

1.服务器驱动协商
以请求的首部字段为参考,在服务器端自动处理。但对用户来说,以浏览器发送的信息作为判定的依据,并不一定能筛选出最优的内容。

2.客户端驱动协商
用户从浏览器显示的可选项列表中手动选择。还可以利用JavaScript脚本在Web页面上自动进行上述选择。比如按照OS的类型或浏览器类型,自行切换成PC版页面或手机版页面。

3.透明协商
是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。

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

类别 原因短语
1XX Informational(信息状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错

4.2 2XX 成功

4.2.1 200 OK

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

4.2.2 204 Not Content

该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不包含实体的主体部分。另外,也不允许返回任何实体的主体。

比如,当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新。

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

4.2.3 206 Partial Content

该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。

响应报文中包含由Content-Range指定范围的实体内容。

3XX 重定向

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

4.3.1 301 Moved Permanently

永久性重定向。


该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。

比如,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。

4.3.2 302 Found

临时性重定向。


和301 Moved Permanently状态码相似,但302状态码代表的资源不是被永久移动,只是临时性质的;已移动的资源对应的URI将来还有可能发生改变。

用户把URI保存成书签,但不会像301状态码出现时那样去更新书签,而是仍旧保留返回302状态码的页面对应的URI。

4.3.3 303 See Other


该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。

303状态码和302 Fount状态码有着相同的功能,但303状态码明确表示客户端应当采用GET方法获取资源,这点与302状态码有区别。

许多HTTP/1.1版以前的浏览器不能正确理解303状态码。虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视为303响应,并且使用GET方法访问在Location中规定的URI,而无视原先的请求方法。所以说使用303是最理想的。


当301、302、303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。

301、302标准是禁止将POST方法改变成GET方法的,但实际使用时大家都会这么做。

4.3.4 304 Not Modified


该状态码表示客户端发送附带条件的请求(附带条件的请求是指:采用GET方法的请求报文中包含If-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)时,服务器端允许请求访问资源,但未满足条件的情况。

304状态码返回时,不包含任何响应的主体部分。

4.3.5 307 Temporary Redirect

临时重定向。

307会遵照浏览器标准,不会从POST变成GET,但是对于处理响应时的行为,每种浏览器有可能出现不同的情况。

4.4 4XX 客户端错误

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

4.4.1 400 Bad Request

该状态码表示请求报文中存在语法错误。

4.4.2 401 Unauthorized

该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。另外若之前已经进行过1次请求,则表示用户认证失败。

返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询(challenge)用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。

4.4.3 403 Forbidden

该状态码表明对请求资源的访问被服务器拒绝了。

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

4.4.4 404 Not Found

该状态码表明服务器上无法找到请求的资源。

4.5 5XX服务器错误

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

4.5.1 500 Internal Server Error

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

4.5.2 503 Service Unavailable

该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

如果实现得知解除以上状况需要时间,最好写入Retry-After首部字段再返回给客户端。