Skip to content

《图解HTTP》读书笔记

《图解HTTP》学习笔记

第一章

1.1-1.2 HTTP基础

Web 使用一种名为 HTTP(HyperText Transfer Protocol,超文本传输协
议 )的协议作为规范,完成从客户端到服务器端等一系列运作流
程。而协议是指规则的约定。可以说Web 是建立在 HTTP 协议上通
信的

HTTP协议的版本:

HTTP/0.9 于1990年问世,无正式的标准

HTTP/1.0 1996年的5月公布,版本被命名为HTTP/1.0,并记载于RFC1945

HTTP/1.1 1997年1月公布的HTTP/1.1是目前(直到现在2024.1.3我在工作中遇到的大部分HTTP仍是1.1)主流的HTTP

协议版本RFC2616

HTTP/2.0 新一代HTTP协议,至今仍未大规模使用

1.3-1.5 网络基础 TCP/IP 与HTTP关系密切的协议

计算机与网络设备相互通信要基于相同方法,这一切都需要一种规则,这种规则被称之为协议。

通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作
的。而 **HTTP 属于它内部的一个子集。**这里的TCP/IP指互联网相关的各类协议组的总称。

image-20241004220944783

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

TCP/IP协议族中预存了各类通用的应用服务,如FTP,和DNS服务

HTTP协议也处于该层(应用层)

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

传输层有两个性质不同的协议:TCP(传输控制协议)和UDP(用户数据报协议)

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

链路层:用来处理连接网络的硬件部分。

image-20241004221507228

利用TCP/IP协议族进行网络通信,会根据分层顺序与对方进行通信。发送端从应用层往下走,接收端从应用层往上走。

为了传输方便,在传输层(TCP 协议)把从应用层处收到的数
据(HTTP 请求报文)进行分割,并在各个报文上打上标记序号及端
口号后转发给网络层。

在网络层(IP 协议),增加作为通信目的地的 MAC 地址后转发给链
路层。这样一来,发往网络的通信请求就准备齐全了。

接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用
层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP
请求。

image-20241004221721144

发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该
层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层
**时会把对应的首部消去。**这一将数据包装起来的做法叫封装。

几乎所有使用网络的系统都会用到 IP(Internert Protocol) 网际协议,TCP/IP协议族中的IP指的就是网际协议 “IP”其实是一种协议的名称,不能与”IP地址搞混”

IP 协议的作用是把各种数据包传送给对方。其中两个重要的条件是 IP 地址和 MAC
地址。IP 地址指明了节点被分配到的地址MAC 地址是指网卡所属的固定地址。IP 地址可以和 MAC 地址进行配对。

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

IP 间的通信依赖 MAC 地址。在网络上,通信双方通常是经过多台计算机和网络设备中转
才能连接到对方。而在进行中转时,会利用下一站中转设备的 MAC
地址来搜索下一个中转目标。这时,会采用 ARP 协议(Address
Resolution Protocol)。ARP 是一种用以解析地址的协议,根据通信方
的 IP 地址就可以反查出对应的 MAC 地址。

在到达通信目标前的中转过程中,那些计算机和路由器等网络设备只能获悉很粗略的传输路线。这种机制称为路由选择(routing)

无论哪台计算机、哪台网络设备,它们都无法全面掌握互联网中的细节。

image-20241004224402530

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

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

TCP协议采用了三次握手,握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) ACK(acknowledgement)

image-20241004224752577

DNS(Domain Name System)和HTTP一样位于应用层的协议,是提供通过域名查找IP地址,或逆向从IP地址反查域名的服务。

1.6各种协议与HTTP协议之间的关系

下图展示了 IP 协议、TCP 协议和 DNS 服务在使用HTTP 协议的通信过程中各自发挥的作用。

image-20241004225847103

URL和URI

URL(Uniform Resource Locator,统一资源定位符)是使用Web浏览器等访问页面时需要输入的网页地址。

URI(Uniform Resource Identifier,统一资源标识符)是由某个协议方案表示的资源的定位标识符。其中协议方案有http、ftp、mailto、telnet、file等,约有30种左右。

URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联
网上所处的位置)。可见 URL 是 URI 的子集。

URI 就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。

image-20241004231104646

绝对 URI 的格式:

image-20241004231536902

第二章

2.1 HTTP 协议用于客户端和服务器端之间的通信

应用 HTTP 协议时,必定是一端担任客户端角色,另一端担任服务器端角色。

image-20241004232259089

2.2 通过请求和响应的交换达成通信

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

请求必定由客户端发出,而服务器端回复响应

image-20241004232357370

具体示例:

image-20241004232536517

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

image-20241004232902905

下面则是从客户端发送给某个 HTTP 服务器端的请求报文中的内容。

1
2
GET /index.htm HTTP/1.1
Host: hackr.jp

接收到请求的服务器,会将请求内容的处理结果以响应的形式返
回。

1
2
3
4
5
6
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
……

起始行开头的 HTTP/1.1 :表示服务器对应的 HTTP 协议版本。

紧挨着的 200 OK 表示请求的处理结果的状态码(status code)和原因
短语(reason-phrase)。下一行显示了创建响应的日期时间,是首部
字段(header field)内的一个属性。

下一行显示了创建响应的日期时间,是首部字段(header field)内的一个属性。

以一空行分隔之后的内容称为资源实体的主体(entity body)。

HTTP响应报文格式:响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代
码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主
体构成。

image-20241004233637586

2.3 HTTP 是不保存状态的协议

image-20241006134435815

2.4 请求 URI 定位资源

image-20241006134504714

当客户端请求访问资源而发送请求时,需要将作为请求报文中的请求 URI 包含在内。

image-20241006134642920

如果不是访问特定资源而是对服务器本身发起请求,可以用一个 * 来代替请求 URI。

以下示例是查询 HTTP 服务器端支持的 HTTP 方法种类。

1
OPTIONS * HTTP/1.1    

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

**GET:获取资源

GET方法用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回相应内容。

image-20241006142139385

image-20241006142155264

image-20241006142201260

**POST:**传输实体主体

POST方法用来传输实体的主体。

POST和GET虽然都能传输实体,但一般不用GET方法进行传输,POST的主要目的并不是获取响应主体内容。

image-20241006142246261

image-20241006142253953

PUT:传输文件

PUT方法用来传输文件。由于安全性问题,一般的Web网站不使用该方法。

image-20241006142351306

image-20241006142413769

(这里相应的意思是请求执行成功但无数据返回)

HEAD:

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

image-20241006142757519

image-20241006142811869

DELETE:删除文件

和PUT一样由于安全原因一般Web网站不使用。

image-20241006142916903

image-20241006142929979

OPTIONS:询问支持的方法

image-20241006143033824

image-20241006143043541

TRACE:追踪路径

TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最后接收到请求的服务器端则返回状态码 200 OK 的响应。客户端通过TRACE方法可以查询到发送出去的请求是怎样被加密/篡改的。

image-20241006143312999

image-20241006143318695

CONNECT:要求用隧道协议连接代理

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

1
CONNECT 代理服务器名:端口号 HTTP版本

image-20241006143458046

image-20241006143503797

2.6使用方法下达命令

这一块内容比较无关紧要。

image-20241006143637556

2.7持久连接节省通信量

在HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接,这意味着每次请求都会造成无谓的TCP连接建立和断开而增加通信量开销。

image-20241006152833999

image-20241006152910271

因此出现了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或
HTTP connection reuse)的方法。其特点为只要任意一段没有明确提出断开连接,则保持TCP连接状态,减轻了服务器的负载,提高Web页面的显示效率。

image-20241006153130650

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

image-20241006153247884

2.8使用Cookie的状态管理

由于HTTP是无状态协议,它不会对之前发生过的请求和相应的状态进行管理。

image-20241006153353937

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

客户端保存由服务器端发送的响应报文中叫做Set-Cookie的首部字段信息,下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值发出。服务器通过客户端发送的Cookie得到之前的状态信息。

image-20241006153715476

image-20241006153722313

1.请求报文(无Cookie时状态)

1
2
3
GET /reader/ HTTP/1.1
Host: hackr.jp
*首部字段内没有Cookie的相关信息

2.响应报文(服务端生成Cookie信息)

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

3.请求报文(自动发送保存着的Cookie信息)

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

第三章

3.1-3.2 HTTP报文

用于 HTTP 协议交互的信息被称为 HTTP 报文。求端(客户端)的HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。

HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。

image-20241006165128464

报文和响应报文的结构

image-20241006165151102

请求报文(上)和响应报文(下)的实例

image-20241006165307378

请求报文和响应报文的首部内容由以下数据组成:

请求行:包含用于请求的方法,请求 URI 和 HTTP 版本。
状态行:包含表明响应结果的状态码,原因短语和 HTTP 版本。
首部字段:包含表示请求和响应的各种条件和属性的各类首部。一般有 4 种首部,分别是:通用首部、请求首部、响应首部和实体首部。(根据名称基本能够得出首部出现在对应的报文类型,通用首部请求和响应报文共有,实体首部约束实体相关的属性)

**其他:**可能包含 HTTP 的 RFC 里未定义的首部(Cookie 等)

3.3编码提升传输速率

HTTP 在传输数据时可以可以在传输过程中通过编码提升传输速率。

报文主体和实体主体的差异:报文是 HTTP 通信中的基本单位,由 8 位组字节流(字节流是指由8位字节组成的连续数据流)组成,通过 HTTP 通信传输。实体作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。

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

压缩传输的内容编码:HTTP协议常用的内容编码有以下几种:gzip(GNU zip)、compress(UNIX系统的标准压缩)、deflate(zlib)、identity(不进行编码)

image-20241006170218993

分割发送的分块传输编码:HTTP请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。这种把实体主体分块的功能称为分块传输编码(Chunked Transfer Coding)。

image-20241006170644942

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

HTTP 协议中采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。通常是在图片或文本文件等上传时使用。
多部分对象集合包含的对象如下。
multipart/form-data
在 Web 表单文件上传时使用。
multipart/byteranges
状态码 206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。
multipart/form-data

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

multipart/byteranges

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HTTP/1.1 206 Partial Content
Date: Fri, 13 Jul 2012 02:45:26 GMT
Last-Modified: Fri, 31 Aug 2007 02:02:20 GMT
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
54
...(范围指定的数据)...
--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–)作为结束。

多部分对象集合的每个部分类型中,都可以含有首部字段。另外,可
以在某个部分中嵌套使用多部分对象集合。有关多部分对象集合更详
细的解释,请参考 RFC2046。

3.5 获取部分内容的范围请求

为了解决传输过程中网络中断的情况,实现类似于断点续传的功能,使用“范围请求”机制来实现。

执行范围请求时,使用首部字段Range。响应会返回状态码为206Partial Content的响应报文,另外对于多重范围请求的,响应会在首部字段Content-Type 标明multipart/byteranges。如果服务器无法响应范围请求则返回200 OK和完整的实体内容。

image-20241006171019556

byte 范围的指定形式:

5001~10 000 字节

1
Range: bytes=5001-10000

从 5001 字节之后全部的

1
Range: bytes=5001-

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

1
Range: bytes=-3000, 5000-7000

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

内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准。

相关字段主要有:

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

内容协商有3种类型:

  • 服务器驱动协商(Server-driven Negotiation )由服务器端进行内容协商。以请求的首部字段为参考,在服务器端自动处理。但对用户来说,以浏览器发送的信息作为判定的依据并不一定能筛选出最优内容。
  • 客户端驱动协商(Agent-driven Negotiation)由客户端进行内容协商的方式。用户从浏览器显示的可选项列表中手动选择。还可以利用JavaScript 脚本在web页面上自动进行上述选择。比如按 OS 的类型或浏览器类型,自行切换成 PC 版页面或手机版页面。
  • 透明协商(Transparent Negotiation)是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法

About this Post

This post is written by Linly, licensed under CC BY-NC 4.0.