阅读 628

婧大带你理一遍HTTP系列知识点 🙈【总结篇】

image.png

前言

有关http的知识点,在面试过程中有关难免会问到,作为一个协议知识点,同时涉及的也是整个http协议知识面。所以这篇文章更像是我这段时间看有关HTTP知识的一些小笔记。

好吧,下面我们开始吧,先放一个导图:

IMG_3080.PNG

一、HTTP协议

1.1、HTTP是什么?

1.1.1、请求-响应式

HTTP是位于应用层,用于客户端和服务器端之间的通信的一种协议,属于请求-响应式,请求由客户端发出,最后服务器响应该请求。

(这里是一个弊端,服务器无法主动向客户端发送请求,如果要实现服务端有什么状态改变导致客户端也需要改变就需要客户端先发送请求,用到的是轮询,但很费时间。因此后面有websocket协议等技术实现实时通信,也就是达到服务器端也可以主动向客户端发请求)

1.1.2、无状态

HTTP是一种无状态协议,对于发送过的请求或者响应都不做持久化处理。事实上HTTP设计成无状态也是因为它可以更快地处理大量的事务。但是大部分情况下无状态无法让我们保存用户的状态。

(在HTTP/1.1(也是无状态) 里面引入了cookie技术,进行状态管理)

二、HTTP报文信息

2.1、HTTP报文

HTTP报文大致可以分成报文首部报文主体(不一定要有)两块,两者由空行来划分.

  • 报文首部:服务及属性器端或客户端出来的请求或响应的内容
  • 空行:回车符+换行符
  • 报文主体:应被发送的数据

image.png

其中请求和响应的报文首部有些字段和区别需要我们了解一下:

  • 请求报文首部:

image.png

  • 响应报文首部:

image.png 区别如下:

  1. 请求行:请求方法+请求URI+HTTP版本
  2. 状态行:HTTP版本+状态码+原因短语
  3. 首部字段:包含请求响应的各种条件和属性的各类首部(通用首部,请求首部,响应首部和实体首部,也可能有cookie之类的其他首部)

三、HTTP 方法

以HTTP/1.1举例

3.1、 GET

获取资源

  1. GET方法用来请求访问已被URI识别的资源
  2. 如果请求的资源是文本,就会保持原样返回

3.2、 POST

传输实体主体

get 和 post的区别

  1. 传送方式:GET通过地址栏传输, POST 通过报文传输。

  2. 传送长度:GET参数有长度限制(受限于url长度),而 POST 无限制

  3. 安全性:GET 的安全性较差,因为所发送的数据是 URL 的一部分。POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。

  4. GET可以被缓存,POST不能被缓存

  5. GET和POST还有一个重大区别,

  • GET产生一个TCP数据包:

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

  • POST产生两个TCP数据包:

对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

3.3、 PUT

传输文件

  1. 但是这个方法自身不带验证机制,存在安全性的问题
  2. 返回的状态码可以是204 No Content 已经从在服务器上添加,无返回数据

3.4、HEAD

获得报文的首部

  1. 不返回报文主体内容
  2. 用于确认URI的有效性及资源更新的日期时间
  • DELETE 删除文件
  1. 和PUT方法相反
  2. 和PUT一样不安全,但是可以配合其他验证机制使用
  3. 返回的状态码可以是204 No Content 已经从服务器删除,无返回数据

3.5、OPTIONS

  1. 查询针对请求指定的资源支持的方法
  2. 响应返回值可以是:Allow:GET,POST,HEAD,OPTIONS(跨域预检)

四、HTTP状态码

1**

信息性状态码——接收内容正在处理

  • 101 协议升级协议

使用场景:比如说使用websocket时 由http协议升级为websocket协议

2**

成功状态码——请求处理完毕

  • 200 成功了,也返回了数据
  • 204 请求成功,无返回数据
  • 206 Content-Range规定的范围内容

3**

重定向状态码——需要进行附加操作以完成请求

  • 301 永久重定向 已经重新分配了新的URI 以后应该使用资源限制所指的URI
  • 302 临时重定向 已经重新分配了新的URI 本次应该使用新的URI访问
  • 304 命中协商缓存

4**

客户端错误状态码——服务器处理请求出错

  • 400 语法错误 参数
  • 401 未认证
  • 403 被拒绝
  • 404 服务器上没有请求的资源

5**

服务器端错误状态码——服务器处理请求出错

  • 500 bug或临时故障
  • 501 客户端的方法参数不支持
  • 503 超出负载,在维修

五、HTTP首部

HTTP首部很多,这里我只是写了一些经常看到的。大家可以自行查阅这里

5.1、请求首部:

这个请求首部字段,就是通知服务器我客户端大概可以支持的东西:

  • 支持的数据的一些媒体类型: Accept
  • 支持的字符集:Accept-Charset
  • 支持的内容编码: Accept-Encoding
  • 支持的语言集相关: Accept-Language

或者是把客户端的一些东西告诉服务器端:

  • 认证信息 :Authorization

告诉服务器请求的资源所在的主机名和端口号:Host 告诉服务器请求的范围: Range

5.2、实体首部:

  • 实体的主体部分的内容编码方式:Content-Encoding
  • 实体部分的大小:Content-Length
  • 实体哪本分符合范围请求: Content-Range (规定这个可能返回206状态码,因为只返回了一定范围的数据)
  • 实体主体内对象的媒体类型:Content-Type

六、HTTP版本总览

6.1、HTTP/0.9

这个版本的HTTP协议时,不支持请求头,只支持GET方法

6.2、HTTP/1.0

相比于HTTP/0.9增加了几个变化:

  • 在请求头中加入了HTTP版本号
  • HTTP开始有请求头和响应头
  • 增加了一些相关的状态码
  • 还有Content-Type,可以传输其他类型的文件

(但是HTTP/1.0性能上有一个很大的问题,那就是每请求一个资源都要新建一个TCP连接,而且是串行请求

TCP连接:

有关TCP连接就是因为HTTP请求响应式在TCP连接基础之上的,而且每次请求数据完成之后,就会断开TCP连接(四次挥手),如果需要多次的HTTP传输,那么TCP也需要断开连接,十分消耗性能。

6.3、HTTP/1.1

HTTP/1.1主要解决HTTP/1.0的网络性能问题,已经增加了一些新的东西:

  • 设置keep-alive 让http重用TCP连接(持久连接、长连接)
  • 增加cache control机制(缓存相关)
  • 正式加入了 OPTIONS 方法,其主要用于 CORS应用(跨域相关)
  • 增加HOST头,因为可以有多个域名解析到同一个IP上,要区分用户是请求的哪个域名,就需要在HTTP的协议中加入域名的信息,而不是被DNS转换过的IP信息。
  • 协议头增加了 Language, Encoding, Type 等头,可以让客户端和服务器端更好的协商
  • 一个请求发送出去了不用等到它的响应,第二个请求就可以发出去了 (支持pipeline网络传输)

6.4、HTTP/2.0

  • HTTP/2.0是一个二进制协议,增加了数据传输的效率
  • 移除了HTTP/1.1中的串行请求,HTTP/2.0可以可以在一个TCP链接中并发请求
  • 会压缩头

(就是说如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分)

6.5、HTTP/3.0

HTTP/2.0已经比之前的版本性能上提高了很多,但是同时它还是有可以改进的地方。比如: 因为HTTP在复用一个TCP的连接,但是底层的TCP协议是不知道上层有多少个HTTP的请求的。

一旦发生丢包,造成的问题就是所有的HTTP请求都必需等待这个丢了的包被重传回来,哪怕丢的那个包不是我这个HTTP请求的

HTTP/2 多请求复用一个TCP连接,一旦发生丢包,就会block住所有的HTTP请求

最后于是HTTP/3把HTTP底层的TCP协议改成了UDP!--- QUIC协议

  • 因为UDP不管顺序,不管丢包
  • QUIC有一套自己的丢包重传和拥塞控制的协议

七、HTTP->HTTPS

7.1、HTTP的特点

从HTTP过渡到HTTPS,首先我们要了解的是HTTP协议的一些特性,比如一个很大的特性就是HTTP它并不安全:

  • 服务端和客户端的对话不是加密的,可能会被窃听
  • 客户端和服务器端都无法认证对方
  • 客户端和服务器端之间传输的数据可能会被修改

基于以上几点,我们需要对HTTP进行改进的就有如下三个方面:

  • 数据传输加密
  • 身份验证
  • 数据完整性保护

7.2、如何使用HTTPS解决

我们先把这些问题了解一下,再来说HTTPS吧;

7.2.1、数据传输加密

使用到的就是对称加密非对称加密

  • 对称加密

打个比方,小明有一把钥匙,它可以用这把钥匙,去把一个箱子锁上(加密),它也可以用这把钥匙把这个箱子打开(解密)。

就是有一个密钥,它可以加密一段信息,也可以对加密后的信息进行解密。

如果我们使用这种方法进行加密的话。首先,客户端和服务器端都有相同的密钥,并且只有双方知道,在这种情况下,如果没有人破解这个密钥,那么就可以保证双方的通信安全了。

但是,要保证它们的密钥是相同的,首先应该由一方生成发给另一方,在这个过程中,怎么才能做到只让传输的双方知道,但是同时又对其他人保密呢?

对称加密好像并不能满足我们的需求,来看看非对称加密:

  • 非对称加密

分析这个过程可能有点漫长,但是可以更清楚的了解非对称加密的使用

两把密钥,通常一把叫做公钥、一把叫私钥,用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。

版本1:服务器端尝试公钥和私钥

  1. 服务器端先把自己的公钥S以明文的方式传输给浏览器。(这里注意是明文)。
  2. 浏览器向服务器传数据前先用这个公钥S加密好再传。
  3. 服务器用它自己的私钥s去解密这个用公钥加密了的数据

(浏览器到服务器的的通信,可以保证数据的可靠)

如果服务器需要传数据给浏览器呢? 4. 服务器用它的私钥加密数据传给浏览器 5. 浏览器用公钥可以解密它 (服务器到浏览器的的通信,不能保证数据的可靠)

image.png

问题:公钥是一开始通过明文传输给浏览器的,这里是不安全的,如果被窃取就会不安全。

版本2: 两对钥匙

上面用的是服务器端生成的一组公钥私钥,但是只可以保证单个方向的安全。那么我们是否可以使用两对钥匙呢?(也就是服务器端和客户端各种都有自己的公钥和私钥。)

  1. 浏览器生成了公钥L,私钥l,服务器生成了公钥F和私钥f
  2. 浏览器把公钥L明文传输给服务器
  3. 服务器吧公钥F明文传输给浏览器
  4. 浏览器向服务器发送内容前用公钥S加密,服务器端收到后用私钥s解密
  5. 服务器向浏览器发送内容前用公钥L加密,浏览器端收到后用私钥l解密

image.png 问题:但是非对称加密算法非常耗时(从图中这来来回回传输感觉是有那么些麻烦哈),而对称加密快很多

版本3:非对称加密+对称加密

  1. 服务器生成用于非对称加密的公钥S和私钥s
  2. 浏览器向服务器请求,服务器把公钥S明文传输给浏览器
  3. 浏览器随机生成一个用于对称加密的密钥M,用公钥S加密后传给服务器
  4. 服务器拿到后用私钥s解密得到密钥M
  5. 这样双方都有密钥M得到。

这样双方之后的数据都可以通过密钥M加密解密 image.png

问题:混合加密可以实现加密通信,但是在客户端其实无法知道这个由服务器端传送过来的

7.2.2、身份验证

使用到的是数字证书(CA),和其他籍贯颁发的公开密钥证书 先简称证书吧

就是说这个证书是客户端和服务器端信赖的第三方。

  1. 服务器端向认证机构申请公开密钥
  2. 认证机构会对已经申请的公开密钥做数字签名,把个已经签名的公开密钥放到公钥证书里面去
  3. 服务器端会把这个重要证书发给客户端,进行公开密钥通信
  4. 客户端对证书上的数字签名进行验证,如果验证通过,可以知道服务器的公开密钥是可信的。

7.2、使用HTTPS通信过程

HTTPS是身披SSL外壳的HTTP

(哈哈哈,用的书上的原小标题哦)

来看看对比HTTP和HTTPS:

image.png

HTTPS协议就是在传输层和应用层直接加了一部分通信接口层,使用的是SSL,TLS可以实现加密,证书和完整性保护这些功能。

综合上面说到的解决的方案,来看看最终HTTPS通信过程。

(看到这图,这12个步骤,强行劝退。。。哈哈哈,开玩笑。虽然步骤多,但是想想分解一下,了解其过程还是很有必要的,咱们继续)

image.png

首先的首先,把上面图中的步骤分成两大块,因为我们上面说到了SSL层是进行加密,证书,和完整性保护的,它完成这些之后,才进入真正的HTTP请求,因此从1-9 都是属于SSL的处理过程,而10-12则是我们知道的HTTP通信过程。

  1. 客户端发送报文给服务器端开始SSL通信

(报文中包含客户端支持的SSL指定版本,加密组件列表-加密算法及密钥长度)

  1. 如果服务器端确定可以使用SSL通信,就会发送响应报文给客户端

(报文中包含SSL版本以及加密组件-从接收客户端的加密组件中筛选出来的)

  1. 服务器把包含公开密钥证书的报文发送给客户端 【证书判断公开密钥是否正确】

  2. 服务器端发送报文通知客户端,最初阶段SSL握手协商部分结束

  3. 客户端生成随机密码串,并用之前的公开密钥进行加密,再通过报文发送给客户端 【随机密码串,相当于之前(非对称加密和对称加密)演示的密钥M】

  4. 客户端继续发送Change Cipher Spec报文,告诉服务器端,之后客户端发送的数据都会使用刚才发送过去的随机密码串进行加密

  5. 客户端发送结束报文,包含连接至今的全部报文的整体校验值。如果服务器可以正确解密该报文,则本次握手协商成功

  6. 服务器端也会发送Change Cipher Spec报文,告诉客户端,之后服务端响应的数据都会使用随机密码串进行加密

  7. 服务器端发送结束报文,包含连接至今的全部报文的整体校验值。如果客户端可以正确解密该报文,则本次握手协商成功

  8. 客户端和服务器端的结束报文交换完毕之后,SSL连接成功。开始进行应用层协议的通信,发送HTTP请求

总结一下整个过程中的一些要点:

  1. HTTPS采用的是非对称和对称加密结合的混合加密算法
  2. 由服务器端发送给客户端的公钥由可信第三方提供。
  3. 当SSL协商完成之后,就会进行我们比较熟悉的HTTP请求响应阶段

上面的过程解决了

  • 数据传输加密
  • 身份验证

但有关 数据完整性保护 却没有提到,是因为有关数据完整性,是在应用层发送数据是附加MAC的报文摘要,MAC能够查知报文是否被篡改,从而保证报文的完整性。

八、浏览器缓存梳理和实践

8.1、强缓存:不需要进行HTTP请求

涉及的首部字段:Expires Cache-Control 需要知道一个他们之间很大的区别就是:

  1. Expires指定资源到期的世界,是服务器端的具体的时间点;(受限于如果修改本地时间,会导致缓存失效)

举个栗子:

  1. Cache-Control设定的是一段时间段,优先级高于Expires
Cache-Control:max-age=300
复制代码

Cache-Control还有一些其他的字段,也可以了解一下哈:

  • no-store :不进行缓存
  • no-cache:不缓存过期了的资源,缓存会向源服务器进行有效期确定之后处理资源
  • public: 其他用户也可以利用缓存
  • private: 响应只以特定的用户作为对象
  • max-age: 指定缓存时间数值
  • s-maxage: 和max-age差不多,但是s-maxage更适用于供多位用户使用的公共缓存服务器。

问题:强缓存判断的是是否超出某个时间或者某个时间段,但是它并没有关注这个服务器端的文件是否已经更新的,可能不能接受到最新的东西,因此需要使用到下面的协商缓存

8.2、协商缓存:需要进行HTTP请求

涉及的首部字段:Last-Modified和If-Modified-Since / ETag和If-None-Match 这里重点关注一下他们各自的过程:

  • Last-Modified和If-Modified-Since
  1. 浏览器向服务器发送请求,客户端在响应头中加入 Last-Modified的header,值是这个资源在服务器上的最后修改时间
  2. 浏览器下一次请求这个资源,检测到之前接收到的 Last-Modified的header,于是添加If-Modified-Since这个header,并且值为Last-Modified的值
  3. 服务器端接收到If-Modified-Since的值会和之前由服务器端发出的Last-Modified的值对比
  4. 如果无变化 304 直接从缓存中读取
  5. 如果 如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200 (就是说服务器端这边已经修改了,因此时间大了)
  • ETag和If-None-Match
  1. 浏览器向服务器端发送请求,返回服务器端生成的一个唯一表示Etag
  2. 浏览器下一次向服务器端发送请求时,将上一次接收到的Etag值放到请求头的If-None-Match里
  3. 服务器接收到后,比较If-None-Match跟自己服务器上该资源的ETag是否一致
  4. 如果一致,返回304 说明资源没有修改
  5. 如果不一致,返回200(包括新的Etag)

8.3、整个缓存流程

1. 浏览器判断是否有缓存

如果没有,直接向服务器端发出请求,返回请求结果和缓存表示,存入缓存,页面加载

如果有,判断是否过期

2. 判断是否过期 强缓存(Expires和Cache-Control)

如果没有过期,直接读取缓存,返回缓存,页面加载

如果过期了,携带If-Modified-Since,If-None-Match,向服务器发送请求,看看资源是否有更新

3. 判断资源是否有更新 协商缓存

如果更新了,重新返回资源和缓存标识,200,并存入缓存

如果没有更新,304 继续使用缓存,读取缓存,返回缓存,页面加载

总结

有关http的知识点真的很多,涉及的知识点也很多,这篇文章就当是这几天看书看文章的一个笔记和总结吧,肯定有很多没有涉及到的和讲明白的知识点,最好是去看书吧。有任何写的错的地方,请在评论区给与建议和意见。万分感激💗

有关理解和实践可能暂时做的还不是很好。继续学习。😹😹😹

image.png

我是婧大,一名大三学崽,希望和你一起学习一起进步。🙆🙆🙆

加油!

文章肯定有写的不好的地方,欢迎评论区指正。

写的不全的地方,也建议大家阅读一下后面的参考文献呀👇👇👇

【参考资料】

图解HTTP

HTTP

深入理解浏览器的缓存机制

深入理解HTTPS原理、过程与实践

文章分类
前端
文章标签