
该文章是我自己学习笔记及理解,希望通篇读完能让你对HTTP和HTTPS有一个更全面的理解,如果错误地方烦请指正。文字较多,全篇预计阅读耗时20分钟。
HTTP
介绍
超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议[1]。HTTP是万维网的数据通信的基础。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。《维基百科》
从 1990 年开始HTTP就在 WWW 上广泛应用。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请求的方法、URI、协议版本、以及包含请求修饰符、客户 信息和内容的类似于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。
- HTTP是基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
- HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。
- HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
- HTTP默认的端口号为80,HTTPS的端口号为443
发展
HTTP刚出现是为了将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器,随着WEB的持续发展,例如CSS、JS丰富了页面展示和基于HTTP协议的ajax增加了我们向服务器获取数据的方式,HTTP也不断的进行优化迭代。
| 版本 | 发布时间 | 主要内容 | 现状 |
|---|---|---|---|
| HTTP/0.9 | 1991 | 无状态、只支持GET请求、无协议头、只支持纯文本 | 已过时 |
| HTTP/1.0 | 1996 | 有协议头、支持GET/POST/HEAD等方法、传输内容不限 | 仍被采用 |
| HTTP/1.1 | 1999 | 默认持久连接、请求管道化、增加缓存处理、增加Host字段、支持断点传输、增加错误通知处理 | 目前最被广泛使用 |
| HTTP/2 | 2015 | 新的二进制格式(帧)、多路复用、header压缩、请求优先级、服务端推送 | 未来的发展趋势 |
| HTTP/3 | 2018.11 | 新的二进制格式(帧)、多路复用、header压缩、请求优先级、服务端推送 | 发展中 |
HTTP/2
HTTP/2继承于Google的SPDY协议。HTTP/2: the Future of the Internet | Akamai这是Akamai公司用来说明HTTP/2的优势所创建的demo。同时请求379张图片,HTTP/2速度占了绝对的优势。

1. 二进制分帧
HTTP 2.0 的所有帧都采用二进制编码
- 帧:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。
- 消息:是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。
- 流:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1、2 … N);
2. 多路复用
之所以速度能有如此优化,主要得益于HTTP2.0的多路复用技术。
有了新的分帧机制后,HTTP/2不再依赖多个TCP 连接去处理更多并发的请求,每个数据流都拆分成很多互不依赖的帧,而这些帧可以交错(乱序发送),还可以分优先级。最后再在另一端根据每个帧首部的流标识符把它们重新组合起来。从始至终,客户端与服务器之间只需要一个连接(同个域名下)即可。

3. 头部压缩
HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如Cookie和User Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。
HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzip或compress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
4. 数据流
因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。
数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。
客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
5. 服务器推送
HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。服务端能在客户端请求静态资源前主动把这些静态资源随着网页一起发给客户端了,省去了客户端建立连接、发起请求等过程,极大提升了速度。
存在的问题
由于底层支持TCP协议的缺陷,导致HTTP/2还是存在一些问题。
- TCP+TLS建立连接耗时 HTTP/2使用TCP协议来传输的,而如果使用HTTPS的话,还需要使用TLS协议进行安全传输,而使用TLS也需要一个握手过程。整个启动过程需要耗时3~4个RTT(往返时延)。
- 队头阻塞 虽然HTTP/2的传输链接可以多路复用,但TCP为了保证传输可靠有序,有个特别的“丢包重传”机制,丢失的包必须要等待重新传输确认,HTTP/2出现丢包时,整个 TCP 都要开始等待重传。例如单个TCP链接同时承载了三路链接,当其中某一路出现丢包,则其他两路都会受到影响,必须从丢包时刻开始重传。如果丢包率过高时,HTTP/2传输不如HTTP/1.1。

HTTP/3

- 实现了类似TCP的流量控制、传输可靠性的功能。 虽然UDP不提供可靠性的传输,但QUIC在UDP的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些TCP中存在的特性。
- 实现了快速握手功能。 由于QUIC是基于UDP的,所以QUIC可以实现使用0-RTT或者1-RTT来建立连接,这意味着QUIC可以用最快的速度来发送和接收数据,这样可以大大提升首次打开页面的速度。0RTT 建连可以说是 QUIC 相比 HTTP2 最大的性能优势。
- 集成了TLS加密功能。 目前QUIC使用的是TLS1.3,相较于早期版本TLS1.3有更多的优点,其中最重要的一点是减少了握手所花费的RTT个数。
- 多路复用,彻底解决TCP中队头阻塞的问题 和TCP不同,QUIC实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了TCP中队头阻塞的问题。

HTTP请求过程
- 域名解析。如用浏览器访问http://hackr.jp/xss/web页面,需要域名系统DNS解析域名hackr.jp,得主机的IP地址 20X.189.105.112,接着结合本机信息封装成HTTP请求数据包。
- 建立连接(TCP三次握手)。在HTTP工作开始之前,客户端首先要通过网络与服务器建立连接,该连接是通过TCP来完成的,一般TCP连接的端口号是80。
- 客户端发送请求。建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。
- 服务器响应。服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
- 服务器关闭连接。
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:
Connection:keep-alive,TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。



Request
一个完整的请求由请求行、请求头和请求体三部分组成。

请求行
请求行包含:请求方法、请求地址(URL)和协议版本。
请求方法
| 方法名 | 功能 |
|---|---|
| GET | 向指定的资源发出“显示”请求,使用 GET 方法应该只用在读取数据上,而不应该用于产生“副作用”的操作中 |
| POST | 指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求文本中。这个请求可能会创建新的资源或者修改现有资源,或两者皆有。 |
| PUT | 向指定资源位置上传其最新内容 |
| DELETE | 请求服务器删除 Request-URI 所标识的资源 |
| OPTIONS | 使服务器传回该资源所支持的所有HTTP请求方法。用*来代替资源名称,向 Web 服务器发送 OPTIONS 请求,可以测试服务器功能是否正常运作 |
| HEAD | 与 GET 方法一样,都是向服务器发出指定资源的请求,只不过服务器将不传回资源的本文部分,它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中关于该资源的信息(原信息或称元数据) |
| TRACE | 显示服务器收到的请求,主要用于测试或诊断 |
| CONNECT | HTTP/1.1 中预留给能够将连接改为通道方式的代理服务器。通常用于 SSL 加密服务器的链接(经由非加密的 HTTP 代理服务器) |
请求头
请求头包含客户端主机名和客户端环境信息。 常见的请求头:
| 名称 | 作用 |
|---|---|
| Authorization | 用于设置身份认证信息 |
| User-Agent | 用户标识,如:OS 和浏览器的类型和版本 |
| Accept-Encoding | 告诉服务器能接受什么编码格式,如 gzip、deflate |
| If-Modified-Since | 值为上一次服务器返回的Last-Modified值,用于确定某个资源是否被更改过,没有更改过就从缓存中读取 |
| If-None-Match | 值为上一次服务器返回的 ETag 值,一般会和If-Modified-Since |
| Cookie | 已有的Cookie |
| Referer | 标识请求引用自哪个地址,比如你从页面 A 跳转到页面 B 时,值为页面 A 的地址 |
| Host | 请求的主机和端口号 |
通用的首部字段:
| 名称 | 作用 |
|---|---|
| Cache-Control | 响应输出到客户端后,服务端通过该属性告诉客户端该怎么控制响应内容的缓存 |
| Date | 表明HTTP报文创建的日期和时间 |
| Trailer | 报文某段的的首部一览 |
| Warning | 错误通知 |
请求体
请求体(又叫请求正文)是 post 请求方式中的请求参数,以 key = value 形式进行存储,多个请求参数之间用&连接,如果请求当中请求体,那么在请求头当中的 Content-Length 属性记录的就是该请求体的长度
Response
一个完整的响应由响应行、响应头和响应体三部分组成。

响应行
响应行包含:协议版本、状态码和状态描述。
响应状态码
-
2XX成功
- 200(OK) 客户端发过来的数据被正常处理
- 204(Not Content) 正常响应,没有实体
- 206(Partial Content) 范围请求,返回部分数据,响应报文中由Content-Range指定实体内容
-
3XX重定向
- 301(Moved Permanently) 永久重定向
- 302(Found) 临时重定向,规范要求,方法名不变,但是都会改变
- 303(See Other) 和302类似,但必须用GET方法
- 304(Not Modified) 状态未改变, 配合(If-Match、If-Modified-Since、If-None_Match、If-Range、If-Unmodified-Since)
- 307(Temporary Redirect) 临时重定向,不该改变请求方法
-
4XX客户端错误
- 400(Bad Request) 请求报文语法错误
- 401 (unauthorized) 需要认证
- 403(Forbidden) 服务器拒绝访问对应的资源
- 404(Not Found) 服务器上无法找到资源
-
5XX服务器错误
- 500(internal sever error)表示服务器端在执行请求时发生了错误
- 503(service unavailable)表明服务器暂时处于超负载或正在停机维护,无法处理请求
响应头
同请求头一样,用来传递附加信息。 常见的响应头:
| 名称 | 作用 |
|---|---|
| Accept-Ranges | 是否接受字节范围请求 |
| ETag | 表示你请求资源的版本,如果该资源发生啦变化,那么这个属性也会跟着变 |
| Location | 在重定向中或者创建新资源时使用 |
| Set-Cookie | 服务端可以设置客户端的cookie |
响应体
响应体也就是网页的正文内容,一般在响应头中会用 Content-Length 来明确响应体的长度,便于浏览器接收,对于大数据量的正文信息,也会使用 chunked 的编码方式。
HTTPS

介绍
回到开篇的图片可知,HTTPS是在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并保护交换数据的隐私与完整性。为了解决HTTP的明文通信,无法验证对方身份和报文的完整性等问题,网景公司(Netscape)在1994年提出了HTTPS协议,随后拓展到互联网上。目前HTTPS已经取代HTTP成为主流协议,而且HTTP/2之后都只能用于HTTPS加密连接。
安全通信的实现

1.保证通信内容不被窃听
-
对称加密 对称密钥(Symmetric-key algorithm)又称为共享密钥加密,加密和解密使用相同的密钥。常见的对称加密算法有DES、3DES、AES、RC5、RC6。对称密钥的优点是计算速度快,但是它有缺点,双方需要都知道密钥才能加解密,因此如何安全的发送密钥给接收者成为了一个问题。
-
非对称加密 公开密钥加密(public-key cryptography)简称公钥加密。公钥可以随意分发,发送方使用公钥进行加密处理,接收方用自己的私有私钥进行解密。这种方式不必担心密钥被攻击者窃听而盗走,但服务器无法验证公钥信息,存在被中间人截获替换的风险,另外非对称加密的传输效率比对称加密低。
-
解决方案:对称加密+非对称加密 对称加密效率高,非对称加密可以防止传输内容被截获。结合两者的优势,HTTPS在交换秘钥阶段采用非对称加密,建立通信后通过对称加密来传递信息。例如发送信息的一方先使用对方的公钥加密对称密钥,对方接收到信息后用私钥进行解密获得对称密钥,之后双方的通信都用对称密钥进行加解密。
2.保证报文不被篡改
- 解决方案:数字签名 由于存在中间节点,传递的信息无法被解密,但仍然可能被随意篡改。为了保证双方发出和接受的是信息一致,可采用数字签名的方式。 发送者先将公钥、个人信息和其他信息用Hash算法生成消息摘要,再用私钥加密生成数字签名。接收方收到公钥、个人信息、其他信息和数字签名,重新用Hash算法生成消息摘要,并用公钥解密数字签名得到的摘要进行校验是否相同。 到此为止,还存在一个最关键的问题:如何在互联网上将公钥安全的传递给对方?
3.验证对方身份
- 解决方案:数字证书 为了防止中间人攻击,掉包公钥,我们需要一个第三方权威机构来管理,让第三方机构用其私钥加密生成数字签名,当接受到身份信息和公钥后再用第三方机构的公钥进行解密来比对信息摘要,这个第三方机构就是CA(Certification Authority)。向CA提交公钥、组织信息、个人信息等信息并申请认证,认证通过后CA会向申请者颁发CA证书,证书内包含:申请者公钥、申请者的组织信息和个人信息、签发机构、CA的信息、有效时间、证书序列号等信息的明文,同时包含一个数字签名。 CA自身的数字证书在我们操作系统刚安装好的时候,这些CA自身的数字证书就已经被微软(或者其它操作系统)安装在操作系统中了。而CA的公钥就包含在其中。这样,CA就可以通过自身的私钥对发布的数字证书进行签名,而在客户端就能够用对应的公钥来对其进行解密,确保了双方能安全传输服务器公钥。

完整过程

- 客户端本地会存放着CA证书机构的公钥,在发起HTTPS请求时,会首先向服务器第索要CA证书,并告发送随机数A、支持的对称加密算法、Hash算法等。
- 服务器收到信息后会将证书、加密算法、Hash算法、随机数B等发给客户端。
- 客户端验证证书是否有效,并使用CA证书机构的公钥解密证书中的数字签名,进行信息比对校验。然后通过验证过后的公钥加密会话秘钥(pre-master key)发送给服务器,这是唯一使用非对称加密的地方。
- 服务器会使用私钥解密得到会话密钥,并通过之前得到的随机数A、随机数B和双方确定的加密算法生成一个最终的会话密钥(master secret),服务器加密一段信息发给客户端进行加密验证。
- 客户端也通过之前随机数A、随机数B和会话密钥生成最终的会话密钥,并对服务器的信息进行解密,若解密成功,双方便结束验证,用会话密钥进行通信。
至此,完成了服务器向客户端的单向验证,若要使客户端对服务器也进行验证操作(双向验证),则需要将CA证书放在客户端。 若采用双向验证,则在步骤2服务器会额外向客户端请求客户端的CA证书信息,客户端在步骤3验证服务器证书后,会将客户端证书发给服务器进行验证。 双向验证能更好的预防中间人攻击,客户端内置了仅接受指定域名的证书,保障了客户端与服务端通信的唯一性和安全性,但要注意证书续期后需重新将证书放入到客户端中。
用信鸽来解释HTTPS
文章 用信鸽来解释 HTTPS 详细描述了整个过程,这里不再累述,想了解的可以自行阅读。
优点&缺点
- 优点(安全性) 尽管HTTPS并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但HTTPS仍是现行架构下最安全的解决方案,大幅增加了中间人攻击的成本。
- 缺点(成本&资源占用) SSL证书需向CA机构购买,功能越强大费用越高;握手过程至少要增加1~2个RTT,且与纯文本通信相比,加密通信会消耗更多的CPU及内存资源。(可以通过性能优化提升性能)
HTTPS性能优化
- CDN接入 HTTPS 增加的延时主要是传输延时 RTT,RTT 的特点是节点越近延时越小,CDN 天然离用户最近,因此选择使用 CDN 作为 HTTPS 接入的入口,将能够极大减少接入延时。CDN 节点通过和业务服务器维持长连接、会话复用和链路质量优化等可控方法,极大减少 HTTPS 带来的延时。
- 会话缓存 虽然前文提到 HTTPS 即使采用会话缓存也要至少1*RTT的延时,但是至少延时已经减少为原来的一半,明显的延时优化;同时,基于会话缓存建立的 HTTPS 连接不需要服务器使用RSA私钥解密获取 Pre-master 信息,可以省去CPU 的消耗。如果业务访问连接集中,缓存命中率高,则HTTPS的接入能力讲明显提升。当前TRP平台的缓存命中率高峰时期大于30%,10k/s的接入资源实际可以承载13k/的接入,收效非常可观。
- 硬件加速 为接入服务器安装专用的SSL硬件加速卡,作用类似 GPU,释放 CPU,能够具有更高的 HTTPS 接入能力且不影响业务程序的。测试某硬件加速卡单卡可以提供35k的解密能力,相当于175核 CPU,至少相当于7台24核的服务器,考虑到接入服务器其它程序的开销,一张硬件卡可以实现接近10台服务器的接入能力。
- 远程解密 本地接入消耗过多的 CPU 资源,浪费了网卡和硬盘等资源,考虑将最消耗 CPU 资源的RSA解密计算任务转移到其它服务器,如此则可以充分发挥服务器的接入能力,充分利用带宽与网卡资源。远程解密服务器可以选择 CPU 负载较低的机器充当,实现机器资源复用,也可以是专门优化的高计算性能的服务器。当前也是 CDN 用于大规模HTTPS接入的解决方案之一。
- SPDY/HTTP2 前面的方法分别从减少传输延时和单机负载的方法提高 HTTPS 接入性能,但是方法都基于不改变 HTTP 协议的基础上提出的优化方法,SPDY/HTTP2 利用 TLS/SSL 带来的优势,通过修改协议的方法来提升 HTTPS 的性能,提高下载速度等。
Charles抓包HTTPS原理
Charles的抓包原理是伪装成中间人,拦截服务器响应,用Charles制作的CA证书替换服务器证书发给客户端,再拦截客户端响应用之前拦截的服务器证书公钥重新加密发给服务器,让双方误以为还是在正常的验证通信中。这一切发生的前提是客户端选择信任并安装Charles的CA证书,否则客户端校验不过CA证书就会报错并中止校验。 具体过程如图:

参考链接
HTTP 协议入门
HTTP 0.9 HTTP 1.0 HTTP 1.1 HTTP 2.0区别
HTTP 基础与变迁
5分钟让你明白HTTP协议
程序员都该懂点 HTTP
前端必备HTTP技能之HTTP请求头响应头中常用字段详解
解密HTTP/2与HTTP/3 的新特性
深入理解HTTPS工作原理
也许,这样理解HTTPS更容易
HTTP与HTTPS的区别
HTTPS协议详解(五):HTTPS性能与优化
扯一扯HTTPS单向认证、双向认证、抓包原理、反抓包策略
From:SimonYe