eziceice / blog

Personal blog for programming
4 stars 2 forks source link

Http详解 #1

Open eziceice opened 5 years ago

eziceice commented 5 years ago

《图解HTTP》读书笔记

第一章

HTTP(HyperText Transfer Protocol,超文转移协议,超文本传输协议的译法并不严谨。)

网络基础 TCP/IP

TCP/IP 协议族

TCP/IP 协议族是互联网相关联的协议的集合。从电缆的规格到IP地址的选定方法、寻找异地用户的方法、双方建立通信的顺序,以及Web页面显示需要处理的步骤,等等。而HTTP是属于它内部的一个子集。

TCP/IP 的分层管理

TCP/IP 协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层。 分层的好处:把各层之间的接口部分规划好之后,每个层次内部的设计就能够自由改动了。而且,层次化之后,设计也变得相对简单。处于应用层上的应用可以只考虑分派给自己的任务,而无需弄清对方在地球上哪个地方、对方的传输路线、是否能确保传输送达等问题。

TCP/IP 通信传输流

缺一张照片P9

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

用HTTP 举例来说:首先作为发送端的客户端在应用层(HTTP协议)发出一个HTTP请求。 接着,在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分隔,并在各个报文上打上标记序号及端口号后转发给网络层。 在网络层(IP协议),增加作为通信目的地的MAC地址后转发给链路层。这就让发往网络的通信请求准备齐全了。 接收端的服务器在链路层接收到数据后,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到客户端发送过来的HTTP请求。

> 缺一张照片P10

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

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

负责传输的 IP 协议

IP(网际协议)位于网络层。该协议的作用是把各种数据包传送给对方。而要保证确实传送到对方那里,则需要满足各类条件。其中最重要的两个条件是 IP 地址和 MAC地址。 IP 地址指明了节点被分配到的地址,MAC地址是指网卡所属的固定地址。IP地址可以和MAC地址进行配对。

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

此处输入图片的描述

确保可靠性的TCP协议

TCP属于传输层,提供可靠的字节流服务。 字节流服务是指:为了方便传输,将大块数据分割成以报文段为单位的数据包进行管理。 这就是为什么下载高清大图时,图片会一块一块地加载。

三次握手 为了准确无误地将数据送达目标处,TCP协议在发送数据的准备阶段采用了三次握手策略(若在握手过程中某个阶段中断,TCP协议会再次以相同的顺序发送相同的数据包)。

> 缺图片P13

当然,除了三次握手,TCP还有其它各种手段确保通信的可靠性。

负责域名解析的 DNS 服务

DNS服务提供域名到IP 地址之间的解析服务。 即可通过域名查找IP,或逆向从IP地址反查域名服务。

此处输入图片的描述

因为域名解析也需要时间,所以可以 提前获取DNS来提升网页加载速度

URI和URL

URI(uniform Resource Identifier) Uniform:规定统一的格式可方便处理多种不同类型的资源。 Resource:可标识的任何东西 Identifier:标识符

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

URI 用字符串标识某一个互联网资源,而URL表示资源的地点。URL是URI的子集。

表示指定的URI,要使用涵盖全部必要信息的绝对URI、绝对URL以及相对URL。相对URL是指从浏览器中基本URI处指定的URL,如 /image/logo.gif

绝对URI的格式如下:

图片P18

第二章 简单的HTTP协议

HTTP协议规定,先从客户端开始建立通信,服务端在没有接收到请求之前不会发送响应。

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

> 图片P24

响应报文基本上由协议版本、状态码、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。

> 图片P25

HTTP是不保存状态的协议

HTTP是无状态协议。自身不对请求和响应之间通信状态进行保存(即不做持久化处理)。 HTTP之所以设计得如此简单,是为了更快地处理大量事物,确保协议的可伸缩性。 HTTP/1.1 随时无状态协议,但可通过 Cookie 技术保存状态。

告知服务器意图的HTTP方法

向请求URI指定的资源发送请求报文时,采用称为方法的命令。方法名区分大小写,主要要用大写字母。

持久连接节省通信量

持久连接

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

此处输入图片的描述

发送请求一份包含多张图片的HTML文档对应的Web页面,会产生大量通信开销。

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

TCP持久连接

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

在HTTP/1.1中,所有连接默认都是持久连接,但在HTTP/1.0内并未标准化。 毫无疑问,除了服务器端,客户端也需要支持持久连接。

管线化

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

注意:尽管HTTP管线化可以克服同域并行请求限制带来的阻塞, 但HTTP/1.x 有严格的串行返回响应机制,服务器通过 TCP 连接返回响应时,就是必须 按照客户端的请求顺序进行响应 ,前一个响应没有完成,下一个响应就不能返回。所以使用“ HTTP 管道”技术时,万一第一个响应时间很长,那么后面的响应处理完了也无法发送,只能被缓存起来,占用服务器内存,这就是传说中的“队首阻塞”。

每个浏览器支持的请求并发数不同,但可在页面中使用多个域名加大并发量(因为浏览器是基于domain的并发控制,而不是page),不过过多的散布会导致DNS解析上付出额外的代价。

使用Cookie的状态管理

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

如果您在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击。

Cookie-free Domains:用户在请求静态资源时,也会发送cookie信息。对于一个拥有多个静态资源的网站,这无疑会产生不必要的流量。因此我们可以启用与主站不同的域名(包括子域名)来放置静态资源。

第三章 HTTP报文内的HTTP信息

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

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

编码提升传输速率

HTTP在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率,但这会消耗更多的CPU等资源。

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

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

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

压缩传输的内容编码

内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。 常见的内容编码有:gzip(GNU zip)、compress(UNIX系统的标准压缩)、deflate(zlib)、identity(不进行编码)

分隔发送的分块传输编码

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

分块传输编码会将实体主体分成多个部分(块)。每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标记。

使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编码前的实体主体。

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

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

获取部分内容的范围请求

下载大尺寸的图片的过程中,如果网络中断,则需要重新下载。因此需要一种可恢复的机制。 实现该功能需要指定下载的实体范围,像这样,指定范围发送的请求叫做范围请求。 执行范围请求时,会用到首部字段Range来指定资源的byte范围。响应会返回状态码206 Partial Content。

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

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

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

返回结果的HTTP状态码

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。 状态码如200 OK,以3为数字和原因短语组成。 数字中的第一位定义了响应类别,后两位无分类。响应类别有以下五种:

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

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

常用的状态码14种:

2XX 成功

3XX 重定向

就算是304,也需要发出请求与接收响应,也会耗费资源和时间。

4XX 客户端错误

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

5XX 服务器错误

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

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

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

HTTP/1.1 规范允许一台HTTP服务器搭建多个Web站点。这是利用虚拟主机(Virtual Host,又称虚拟服务器)的功能。

在互联网上,域名通过DNS服务映射到IP地址之后访问目标网站。可见,当请求发送到服务器时,已经是以IP地址形式访问了。所以,当一台托管了两个域名的服务器接收到请求时就需要弄清楚究竟要访问哪个域名。 在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。

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

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

代理

代理不改变请求URI,会直接发送给前方持有资源的目标服务器。 持有资源实体的服务器被称为源服务器。

> P68
例如:
> 淘宝的via

每次通过代理服务器转发请求或响应式,会追加写入via首部信息。

使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的,等等。

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

网关

网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务。 利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。

隧道

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

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

保存资源的缓存

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

缓存服务器是代理服务器的一种。当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。

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

缓存的有效期限

对于缓存服务器和客户端浏览器,当判定缓存过期或客户端要求,会向源服务器确认资源的有效性。若失效,浏览器会再次请求新资源。

第六章 HTTP首部

HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器端分别处理请求和响应提供所需要的信息。

HTTP请求报文:由方法、URI、HTTP版本、HTTP首部字段等构成。 HTTP响应报文:由HTTP版本、状态码(数字和原因短语)、HTTP首部字段 3 部分组成。

HTTP首部字段

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

4种HTTP首部字段类型

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

HTTP/1.1首部字段一览

通用首部字段

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

Cache-Control的no-cache指令代表不缓存过期的资源,而不是不缓存。no-store才是真正不进行缓存。 Connection首部字段的值为close时,代表服务器想明确断开连接(HTTP/1.1默认都是持久连接)

请求首部字段

首部字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言
Authorization Web认证信息
Expect 期待服务器的行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-Node-Match 比较实体标记(与If-Match相反)
If-Range 资源未更新时发送实体Byte的范围请求
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中URI的原始获取方
TE 传输编码的优先级
User-Agent HTTP客户端程序的信息

该表的Accept*字段都可以指定权重q(0-1)。当服务器提供多种内容时,将会首先返回权重最高的。 If-xxx请求首部字段都称为条件请求,服务器接收到附带条件的请求后,只有判断指定条件为真时,才回执行请求。 Referer 的正确拼写应该是Referrer。当直接在浏览器的地址栏输入URI时,或处于安全考虑时,可不发该首部字段。

响应首部字段

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

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

实体首部字段

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

为Cookie服务的首部字段

首部字段名 说明 首部类型
Set-Cookie 开始状态管理所使用的Cookie信息 响应首部字段
Cookie 服务器接收到的Cookie信息 请求首部字段

Set-Cookie字段的属性

属性 说明
NAME=VALUE 赋予Cookie的名称和其值(必需项)
expires=DATE Cookie的有效期(若不明确指定则默认为浏览器关闭前为止)
path=Path 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录)
domain=域名 作为Cookie适用对象的域名(若不指定则默认为创建Cookie的服务器的域名)
Secure 仅在HTTPS安全通信时才会发送Cookie
HttpOnly 加以限制,使Cookie不能被JavaSript脚本访问

expires:一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显示删除Cookie的方法。但可通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。 path:用来指定cookie被发送到服务器的哪一个目录路径下(即被服务器哪个路径接收cookie),其中"/"指的是站点根目录,可在同一台服务器(即使有多个应用)内共享该cookie。

第七章 确保Web安全的HTTPS

HTTP的缺点

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

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

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

HTTP/1.1 使用的认证方式如下所示:

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

HTTP的瓶颈

使用HTTP协议探知服务器上是否有内容更新,就必须频繁地从客户端到服务器端进行确认。如果服务器上没有内容更新,那么就会产生徒劳的通信。 若想在现有Web实现所需的功能,一下这些HTTP标准就会成为瓶颈:

Comet 的解决方法

通常,服务器接收到请求,在处理完毕后就立即返回响应,但为了实现推送功能,Comet会先将响应置于挂起状态,当服务器端有内容更新时,再返回该响应。 内容上虽然可以做到实时更新,但为了保留响应,一次连接的持续时间也变长了。期间,为了维持连接会消耗更多的资源。另外,Comet仍未解决HTTP协议的本身存在的问题。

SPDY

Google 在2010年发布了 SPDY,其开发目标旨在解决HTTP的性能瓶颈,缩短Web页面的加载时间。 SPDY没有完全改写HTTP协议,而是在TCP/IP的应用层与运输层之间通过新加会话层的形式运作。同时,考虑到安全性问题,SPDY规定通信中使用SSL。

> P184

SPDY以会话层的形式加入,控制对数据的流动,但还是采用HTTP建立通信连接。因此,可照常使用HTTP的GET和POST等方法、Cookie以及HTTP报文等。

使用 SPDY后,HTTP协议额外获得以下功能。

使用浏览器进行全双工通信的 WebSocket

利用Ajax和Comet技术进行通信可以提升Web的浏览速度。但问题在于通信若使用HTTP协议,就无法彻底解决瓶颈问题。

WebSocket技术主要是为了解决Ajax和Comet里XMLHttpRequst附带的缺陷所引起的问题。

一旦Web服务器与客户端之间建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML或图片等任意格式的数据。

WebSocket的主要特点:

为了实现WebSocket通信,在HTTP连接建立之后,需要完成一次“握手”的步骤。

成功握手确立WebSocket连接后,通信时不再使用HTTP的数据帧,而采用WebSocket独立的数据帧。

由于是建立在HTTP基础上的协议,因此连接的发起方仍是客户端,而一旦确立WebSocket通信连接,不论服务器端还是客户端,任意一方都可直接向对方发送报文。

HTTP/2.0

HTTP2中英对照版 HTTP/2.0 相比1.0有哪些重大改进?

第十一章 Web攻击技术

简单的HTTP协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象。应用HTTP协议的服务器和客户端,以及运行在服务器上的Web应用等资源才是攻击目标。

HTTP不具备必要的安全功能,就拿远程登录时会用到的SSH协议来说,SSH具备协议级别的认证及会话管理等功能,HTTP协议则没有。另外在架设SSH服务方面,任何人都可以轻易地创建安全等级高的服务。而HTTP即使已假设好服务器,但开发者需要自行设计并开发认证及会话管理功能来满足Web应用的安全。而自行设计就意味着会出现各种形形色色的实现,可仍在运作的Web应用背后就会隐藏着各种容易被攻击者滥用的安全漏洞的Bug。

因输出值转义不完全引发的安全漏洞

因设置或设计上的缺陷引发的安全漏洞

因会话管理疏忽引发的安全漏洞

其它安全漏洞

自问自答:

  1. URI与URL的区别
    答:URI 用字符串(包括地址)标识某一个互联网资源,而URL表示资源的地点。因此URL是URI的子集。
  2. GET与POST的区别
    可以看看这篇文章 浅谈HTTP中Get与Post的区别。我个人认为主要的一点是:URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。 关于URL和queryString长度限制的相关链接:
  3. 301与302区别
    答:301是永久性重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。 302是临时性重定向,搜索引擎会抓取新的内容而保留旧的网址。因为服务器返回302代码,搜索引擎认为新的网址只是暂时的。
  4. 为什么三次握手,二次不可以吗?
    答:不可以,只有完成3次才能进行后续操作,若在握手过程中某个阶段中断,TCP协议会再次以相同的顺序发送相同的数据包。而且,第三次握手是客户端为了让服务器知道它是否接收到响应,确保连接建立成功。
  5. 为什么有时候下载高清大图时,图片会一块一块地加载。
    答:这就是因为设置了http请求的长度,这样就可以分块的加载资源文件。在请求报文中使用Range属性,在响应报文中使用Content-Type属性都可以指定一定字节范围的http请求。