Http-超文本传输协议-详解

一、HTTP基本概念

1.1、Http是什么?

HTTP是 超文本传输协议 分为三个部分

  1. 超文本

它就是超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键有超链接,能从一个超文本跳转到另外一个超文本。

  1. 传输

所谓的「传输」,很好理解,就是把一堆东西从 A 点搬到 B 点,或者从 B 点 搬到 A 点。允许中间有中转或接力
HTTP 是一个在计算机世界里专门用来在两点之间传输数据的约定和规范。

  1. 协议

HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范)。

HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。

1.2、HTTP常见 的状态码有哪些?

在这里插入图片描述

1xx :状态属于提示信息,是协议处理中的一种中间状态,实际上用的比较少
2xx :表示服务器成功处理了客户端的请求,也是我们希望看到的状态

  1. 200:成功状态码,一切ok;
  2. 204: 也是成功状态码,但无响应的body数据;
  3. 206:应用于 HTTP 分块下载 或 断点续传,表示响应返回的 body 数据 并不是资源的全部,而是一部分,也是成功状态码;

3xx:表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。

  1. 301:表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。

  2. 302 :表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。

301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

  1. 304 :不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。

4xx:表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。

  1. 400:表示客户端请求的报文有错误,但只是个笼统的错误。
  2. 403 :表示服务器禁止访问资源,并不是客户端的请求出错。
  3. 404:表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

5xx:表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。

  1. 500:与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
  2. 501:表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
  3. 502:通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
  4. 503:表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

1.3、HTTP常见的字段有哪些

  1. host
    客户端发送请求时,用来指定服务器的域名。 ---- Host: www.A.com

  2. Content-Length
    表明本次回应的数据长度 ------Content-Length: 1000 服务器回应的数据长度为 1000字节

  3. Connection
    最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用 ------Connection: keep-alive 持久连接

  4. Content-type
    用于服务器回应时,告诉客户端,本次数据是什么格式。
    —Content-Type: text/html; charset=utf-8 HTML格式数据,编码格式为 UTF-8
    —Accept: / :声明自己可以接受任何格式的数据。

  5. Content-Encoding
    说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式 -----Content-Encoding: gzip 仅支持 gzip 数据压缩格式

二、GET && POST

2.1、Get && post 区别

GET

GET请求的参数位置一般在 URL中,URL 只支持 Ascll ,所以 get请求的参数只允许 ASCLL 字符,而且浏览器会对URL长度有限制

POST

POST 请求携带数据的位置一般是写在报文 body 中, body 中的数据可以是任意格式的数据,只要客户端与服务端协商好即可,而且浏览器不会对 body 大小做限制。

2.2、GET 和 POST 方法都是安全和幂等的吗?

在 HTTP协议中的安全 指:请求方法不会 破坏服务器上的资源
幂等:多次执行相同操作,结果是相同的

从 RFC 规范定义来讲

  1. Get 是 只读操作,无论操作多少次 对服务器的数据是安全的,结果也是相同的。
    所以 GET 是 安全 、幂等 并且可缓存。
  2. POST 是 新增或 修改操作,会修改服务器的资源,所以是不安全的,执行的结果也是不同,所以是 不幂等的,所以也不可被缓存

实际来讲

开发人员 可能会用 get 请求来执行 新增 、删除的操作 这样 Get 就不安全,不幂等,也不可被缓存。
也可能会用 post 请求执行 查询 操作 ,是 安全 、幂等 并且可缓存;

如果安全的定义是数据会不会被泄露
然 POST 用 body 传输数据,而 GET 用 URL 传输,这样数据会在浏览器地址拦容易看到,但是并不能说 GET 不如 POST 安全的。

因为 HTTP 传输的内容都是明文的,虽然在浏览器地址拦看不到 POST 提交的 body 数据,但是只要抓个包就都能看到了。

所以,要避免传输过程中数据被窃取,就要使用 HTTPS 协议,这样所有 HTTP 的数据都会被加密传输。

2.3、GET 请求可以带 body 吗?

RFC 规范并没有规定 GET 请求不能带 body 的。理论上,任何请求都可以带 body 的。只是因为 RFC 规范定义的 GET 请求是获取资源,所以根据这个语义不需要用到 body。

另外,URL 中的查询参数也不是 GET 所独有的,POST 请求的 URL 中也可以有参数的。

总之 RFC规范 和 实际开发 还是有区别的 但是还是最好按照 RFC 规范开发,显得 专业些~~~

三、HTTP缓存技术

对于一些 每次请求的结果都是一样的 我们可以把这对 请求-响应的数据 缓存在本地,下次就可以直接读取本地数据。提高性能

HTTP缓存实现方式有两种: 强制缓存、协商缓存

3.1、强制缓存

强制缓存:只要浏览器判断缓存没有过期,就直接使用缓存

如下图中,返回的是 200 状态码,但在 size 项中标识的是 from disk cache,就是使用了强制缓存。
在这里插入图片描述

强制缓存的实现
强缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们都用来表示资源在客户端缓存的有效期:

Cache-Control, 是一个相对时间;
Expires,是一个绝对时间;
如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话,Cache-Control的优先级高于 Expires 。

Cache-control 选项更多一些,设置更加精细,所以建议使用 Cache-Control 来实现强缓存。具体的实现流程如下:

  1. 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小;
  2. 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器;
  3. 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control。

3.2、协商缓存

你可能会看到过某些请求的响应码是
304,这个是告诉浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。

在这里插入杀杀杀是是s片描述
上图就是一个协商缓存的过程,所以协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存。

协商缓存实现

  1. 第一种::请求头部中的 If-Modified-Since 字段与响应头部中的 Last-Modified 字段实现
    1、响应头部中的 Last-Modified:标示这个响应资源的最后修改时间;
    2、请求头部中的 If-Modified-Since:当资源过期了,发现响应头中具有 Last-Modified 声明,则再次发起请求的时候带上 Last-Modified 的时间,服务器收到请求后发现有 If-Modified-Since 则与被请求资源的最后修改时间进行对比(Last-Modified),如果最后修改时间较新(大),说明资源又被改过,则返回最新资源,HTTP 200 OK;如果最后修改时间较旧(小),说明资源无新修改,响应 HTTP 304 走缓存。

  2. 第二种头部中的 If-None-Match 字段与响应头部中的 ETag 字段
    1、当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 ETag 唯一标识,这个唯一标识的值是根据当前请求的资源生成的;
    2、当浏览器再次请求访问服务器中的该资源时,首先会先检查强制缓存是否过期,如果没有过期,则直接使用本地缓存;如果缓存过期了,会在 Request 头部加上 If-None-Match 字段,该字段的值就是 ETag 唯一标识;
    3、服务器再次收到请求后,会根据请求中的 If-None-Match 值与当前请求的资源生成的唯一标识进行比较:
    如果值相等,则返回 304 Not Modified,不会返回资源;
    如果不相等,则返回 200 状态码和返回资源,并在 Response 头部加上新的 ETag 唯一标识;
    如果浏览器收到 304 的请求响应状态码,则会从本地缓存中加载资源,否则更新资源。

注意,协商缓存这两个字段都需要配合强制缓存中 Cache-control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求

在这里插入图片描述

四、HTTP特性

4.1、优点

  1. 简单
    HTTP 基本的报文格式就是 header + body,头部信息也是 key-value 简单文本的形式,易于理解

  2. 灵活和易于扩展
    HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充。

  3. 应用广泛和跨平台.
    HTTP 的应用范围非常的广泛,同时天然具有跨平台的优越性。

4.2、缺点

  1. 无状态
    无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。
    无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。
    例如:登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。

  2. 不安全
    通信使用明文(不加密),内容可能会被窃听。比如,账号信息容易泄漏,那你号没了。
    不验证通信方的身份,因此有可能遭遇伪装。比如,访问假的淘宝、拼多多,那你钱没了。
    无法证明报文的完整性,所以有可能已遭篡改。比如,网页上植入垃圾广告,视觉污染,眼没了。

4.3、Cookie 和 session 解决 无状态缺点

对于无状态的 缺点 ,可以使用 cookie 和 session 来解决
在这里插入图片描述
客户端发送请求 到 服务器端,服务器 生成 cookie 和 对应的session 信息,并将 cookie 返回给 客户端 ,客户端再次发送请求 携带 cookie ,服务端 拿到 cookie 查到 对应的 session ,可知 用户是谁

4.4、TCP/IP 七层和四层

七层
在这里插入图片描述

四层
在这里插入图片描述

HTTPS是在 会话层 做的加密 SSL\TLS

4.5、三次握手 和 四次挥手

三次握手建立连接
在这里插入图片描述

形象解释
一次握手:客户端 向 服务端发消息:在吗
二次握手:服务端 回 客户端:在的
三次握手:客户端向服务端发消息:好的 那我去找你。

为什么是三次握手?不是两次或者四次?

  1. 如果是两次握手:服务端 并不能确定 客户端接收到其消息,这样只能 客户端向服务端发送消息了
  2. 如果是四次握手:三次握手可以建立连接 ,为什么要多握手一次,做这个无用功呢

四次挥手断开连接

在这里插入图片描述

形象解释
一次挥手:客户端 向 服务端发消息:断开连接
二次挥手:服务端 回 客户端:我考虑下
三次挥手:服务端 回 客户端:好的 那就断开吧。
四次挥手:客户端等了一会,服务器并再没有向客户端发消息,客户端就自己也关闭连接

为什么是四次挥手?三次挥手不可以吗?
如果是三次挥手, 客户端向服务器发送 关闭请求后,服务器将信息一起发送过去,这样会造成数据丢失,所以 客户端等待 ,服务器发完信息,是很有必要的。

4.6、长连接 和短连接

在这里插入图片描述
短连接

每次请求前会建立连接,请求 后都会断开连接。

长连接
请求前会建立连接,超过一定时间没有任何数据交互,服务端就会主动断开这个连接。

五、HTTP && HTTPS

5.1、区别

  1. Http 是明文传输,存在安全风险,Https 解决了其不安全的缺陷,加入了 SSL/TLS安全协议,使得可以加密传输。
  2. HTTP三次握手后便可数据传输 ,HTTPS在三次握手后 进行 SSL/TLS的握手的过程,保证 加密报文传输。
  3. HTTP端口是 80, HTTPS 端口是443.
  4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

5.2、HTTPS如何实现加密传输

HTTPS在三次握手后 进行 SSL/TLS的握手的过程,保证 加密报文传输。
在这里插入图片描述

具体实现

  1. 混合加密的方式实现信息的机密性,解决了窃听的风险。
  2. 摘要算法的方式来实现数据完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
  3. 将服务器公钥放入到数字证书中,解决了冒充的风险。

1、混合加密
HTTPS 采用的对称加密和非对称加密结合的 混合加密方式
在这里插入图片描述

  1. 在通信建立之前采用 非对称加密的方式 交换 会话密钥,后续不再使用 非对称加密
  2. 在通信过程中 全部使用 对称加密的 会话密钥的方式 加密 明文数据。

采用「混合加密」的方式的原因:

  1. 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
  2. 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

2. 摘要算法 类似签名 保存数据完整性
在这里插入图片描述
客户端在发送明文之前会通过摘要算法算出明文的「指纹」,发送的时候把「指纹 + 明文」一同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。

3. 数字证书

客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

这就存在些问题,如何保证公钥不被篡改和信任度?

所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

在这里插入图片描述

5.3、HTTPS 是如何建立连接的?其间交互了什么?

HTTPS在三次握手后 进行 SSL/TLS的握手的过程。

SSL/TLS协议 基本流程

  1. 客户端向服务器索要并验证服务器的公钥。
  2. 双方协商生产「会话秘钥」。
  3. 双方采用「会话秘钥」进行加密通信。

前两步也就是 SSL/TLS 的建立过程,也就是 TLS 握手阶段。

SSL/TLS 的「握手阶段」涉及四次通信,可见下图:
在这里插入图片描述
SSL/TLS 协议建立的详细流程:

  1. ClientHello

首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。

在这一步,客户端主要向服务器发送以下信息:

(1)客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。

(2)客户端生产的随机数(Client Random),后面用于生成「会话秘钥」条件之一。

(3)客户端支持的密码套件列表,如 RSA 加密算法。

  1. SeverHello

服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:

(1)确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。

(2)服务器生产的随机数(Server Random),也是后面用于生产「会话秘钥」条件之一。

(3)确认的密码套件列表,如 RSA 加密算法。

(4)服务器的数字证书。

3.客户端回应

客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。

如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:

(1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。

(2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

(3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。

上面第一项的随机数是整个握手阶段的第三个随机数,会发给服务端,所以这个随机数客户端和服务端都是一样的。

服务器和客户端有了这三个随机数(Client Random、Server Random、pre-master key),接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。

  1. 服务器的最后回应

服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。

然后,向客户端发送最后的信息:

(1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。

至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。

问答阶段

1、“https和http相比,就是传输的内容多了对称加密,可以这么理解吗?”

  1. 建立连接时候:https 比 http多了 TLS 的握手过程;
  2. 传输内容的时候:https 会把数据进行加密,通常是对称加密数据

2、我看文中 TLS 和 SSL 没有做区分,这两个需要区分吗?

  1. 这两实际上是一个东西。

==============================摘自 敖丙 公众号 HTTP 文章-------------------------------------------------------------------------