前端---梳理 http 知识体系 1

2021年11月26日 阅读数:3
这篇文章主要向大家介绍前端---梳理 http 知识体系 1,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

 最近看了http相关的知识点,以为仍是有必要整理下,这样对本身的网络知识体系也有帮助。nginx

HTTP 是什么

 http叫超文本传输协议,能够拆成超文本传输协议来理解

协议web

  http 是一个用在计算机里面的协议,使用计算机通讯之间的一个规范,以及相关各类控制和错误处理方式。简单的说就是约定、规则。算法

传输浏览器

  http 是一个在计算机世界里专门用来在计算机之间传输数据的约定和规范。缓存

超文本安全

  所谓“超文本”,就是“超越了普通文本的文本”,它是文字、图片、音频和视频等的混合体,最关键的是含有“超连接”,可以从一个“超文本”跳跃到另外一个“超文本”,造成复杂的非线性、网状的结构关系服务器

http 不是一个孤立的协议websocket

  http 是一个应用层协议, 一般跑在 TCP/IP 协议栈之上,依靠 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通讯。此外,还有一些协议依赖于 HTTP,例如 WebSocket、HTTPDNS 等。cookie

HTTP 优缺点

特色

 灵活可扩展

  语法上只规定了基本格式,空格分隔单词,换行分隔字段等。以及传输上不只能够传输文本,还能够传输图片,视频等任意数据。网络

可靠传输

  由于 HTTP 协议是基于 TCP/IP 的,而 TCP 自己是一个“可靠”的传输协议,因此 HTTP 天然也就继承了这个特性,可以在请求方和应答方之间“可靠”地传输数据。

请求-应答模式

  请求 - 应答模式是 HTTP 协议最根本的通讯模型,简单的理解就是,一方发消息,一方接收消息

无状态

  整个协议里没有规定任何的“状态”,客户端和服务器永远是处在一种“无知”的状态。创建链接前二者互不知情,每次收发的报文也都是互相独立的,没有任何的联系

缺点

不安全

  明文传输,其次HTTP 协议也不支持“完整性校验”,数据在传输过程当中容易被窜改而没法验证真伪。为了解决 HTTP 不安全的缺点,因此就出现了 HTTPS

性能

  http 是请求-应答模式,发起的请求相似一个队列,先进先出,会存在对头阻塞问题

 无状态

  这个无状态主要看应用场景,对于不须要上下文状态的,这个就是优势,对于须要记录状态的,这个就是缺点,固然这个能够经过其余方式来作,好比 cookie,token 等

HTTP 报文结构

HTTP 协议的请求报文和响应报文的结构基本相同,由三大部分组成:

  1. 起始行(start line):描述请求或响应的基本信息
  2. 头部字段集合(header):使用 key-value 形式更详细地说明报文
  3. 消息正文(entity):实际传输的数据,它不必定是纯文本,能够是图片、视频等二进制数据

前两部分起始行和头部字段常常又合称为“请求头”或“响应头”,消息正文又称为“实体”,但与“header”对应,不少时候就直接称为“body”。

HTTP 协议规定报文必须有 header,但能够没有 body,并且在 header 以后必需要有一个“空行”(区分body 与 head 分割),也就是CRLF。

  HTTP 头字段很是灵活,不只可使用标准里的 Host、Connection 等已有头,也能够任意添加自定义头,这就给 HTTP 协议带来了很是好的灵活、扩展性。

请求行

报文里的起始行也就是请求行(request line),它简要地描述了客户端想要如何操做服务器端的资源。

状态行

  这里它不叫“响应行”,而是叫“状态行”(status line),意思是服务器响应的状态。

 

 头部字段

  请求行或状态行再加上头部字段集合就构成了 HTTP 报文里完整的请求头或响应头 如图:

HTTP 常见状态码

RFC 规定 HTTP 的状态码为「三位数」,第一个数字定义了响应的类别,被分为五类:

  • 1xx: 表明请求已被接受,须要继续处理。
  • 2xx: 表示成功状态。
  • 3xx: 重定向状态。
  • 4xx: 客户端错误。
  • 5xx: 服务器端错误。

  客户端做为请求的发起方,获取响应报文后,须要经过状态码知道请求是否被正确处理,是否要再次发送请求,若是出错了缘由又是什么。这样才能进行下一步的动做,要么发送新请求,要么改正错误重发请求。

  服务器端做为请求的接收方,也应该很好地运用状态码。在处理请求时,选择最恰当的状态码回复客户端,告知客户端处理的结果,指示客户端下一步应该如何行动。特别是在出错的时候,尽可能不要简单地返 400、500 这样意思含糊不清的状态码。

  目前 RFC 标准里总共有 41 个状态码,但状态码的定义是开放的,容许自行扩展。因此 Apache、Nginx 等 Web 服务器都定义了一些专有的状态码。若是你本身开发 Web 应用,也彻底能够在不冲突的前提下定义新的代码。

1xx 信息类

  接受的请求正在处理,信息类状态码。

2xx 成功

  • 200 OK 表示从客户端发来的请求在服务器端被正确请求。
  • 204 No content,表示请求成功,但没有资源可返回。
  • 206 Partial Content,该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求 响应报文中包含由 「Content-Range」 指定范围的实体内容。

3xx 重定向

  • 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL,这时应该按 Location 首部字段提示的 URI 从新保存。
  • 302 found,临时性重定向,表示资源临时被分配了新的 URL。
  • 304 资源未修改,拿缓存的资源

 

 

 

  301 和 302 都会在响应头里使用字段 Location 指明后续要跳转的 URI,最终的效果很类似,浏览器都会重定向到新的 URI。二者的根本区别在于语义,一个是“永久”,一个是“临时”

好比,你的网站升级到了 HTTPS,原来的 HTTP 不打算用了,这就是“永久”的,因此要配置 301 跳转,把全部的 HTTP 流量都切换到 HTTPS。

  304 Not Modified 是一个比较有意思的状态码,它用于 If-Modified-Since 等条件请求,表示资源未修改,用于缓存控制。它不具备一般的跳转含义,但能够理解成“重定向已到缓存的文件”(即“缓存重定向”)。

4xx 客户端错误

  • 400 bad request,通用的错误码,请求报文存在语法错误。
  • 403 forbidden,表示对请求资源的访问被服务器拒绝,服务器常常访问资源。
  • 404 not found,表示在服务器上没有找到请求的资源。
  • 405 Method Not Allowed,服务器禁止使用该方法,客户端能够经过options方法来查看服务器容许的访问方法

5xx 服务的错误

  • 500 internal sever error,表示服务器端在执行请求时发生了错误。
  • 502 Bad Gateway,服务器自身是正常的,访问的时候出了问题,具体啥错误咱们不知道。
  • 503 service unavailable,代表服务器暂时处于超负载或正在停机维护,没法处理请求。

HTTP主要版本之间的差别

http0.9

  20 世纪 90 年代初期的互联网世界很是简陋,计算机处理能力低,存储容量小,网速很慢,这一时期的 HTTP 被定义为 0.9 版,结构比较简单,只容许用“GET”动做从服务器上获取 HTML 文档,而且在响应请求以后当即关闭链接,功能很是有限,该版本已通过时。

http1.0

  相比0.9版本,1.0版本增长了不少功能,例如:

  • 传输的数据再也不仅限于文本,图像、视频、音频都能传输
  • 引入了 HTTP Header(头部)的概念,让 HTTP 处理请求和响应更加灵活
  • 增长了响应状态码,标记可能的错误缘由
  • 增长了 HEAD、POST 等新方法
可是此时的hppt1.0 并非一个“标准”,只是记录已有实践和模式的一份参考文档,不具备实际的约束力

http1.1

  http1.1是对 http1.0 的小幅度修改。但一个重要的区别是:它是一个“正式的标准

  • 明确了链接管理,容许持久链接,即TCP创建链接以后默认不关闭,能够被多个请求复用,不用声明Connection: keep-alive
  • 增长了 PUT、DELETE 等新的方法
  • 增长了缓存管理和控制,如增长了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效
  • 支持断点续传,经过使用请求头中的 Range 来实现。
  • 容许响应数据分块(chunked)传输,有利于传输大文件
  • 强制要求 请求头带上Host 头,让互联网主机托管成为可能。

其中http1.1 版本是目前主流版本。

http2

  随着互联网在飞速发展,目前http1.0 不符合如今的网络环境要求了,因此谷歌在1.0 的基础上提出了SPDY 协议,优化了1.0。http/2 的制定充分考虑了现今互联网的现状:宽带、移动、不安全,在高度兼容 http/1.1 的同时在性能改善方面作了很大努力,

主要的特色有:

  • 二进制协议,再也不是纯文本,包括头部字段、body 的实体数据都是二进制,而且统称为"帧":头信息帧和数据帧
  • 可发起多个请求,废弃了 1.1 里的管道
  • 增长流、二进制分帧的概念
  •  多路复用TCP链接,在一个链接里,客户端和浏览器均可以同时发送多个请求或回应,且不用按顺序一一对应,这样子解决了http队头阻塞的问题。
  • 使用专用算法(HPACK)压缩头部,减小数据传输量
  • 容许服务器主动向客户端推送数据

http3

  在http2 的基础之上又进一步优化,出现了QUIC 协议,后面改名为http/3,HTTP/3 目前正式进入了标准化制订阶段。

TCP/IP 协议栈

  tcp/ip 是一个有层次的协议栈,TCP/IP 协议总共有四层,就像搭积木同样,每一层须要下层的支撑,同时又支撑着上层,任何一层被抽掉均可能会致使整个协议栈坍塌。每一层只作本身的事情,而后把结果给其余层,这样的结构责任清晰,便于扩展

第一层:连接层(数据链路层)负责在以太网、WiFi 这样的底层网络上发送原始数据包,工做在网卡这个层次,使用 MAC 地址来标记网络上的设备,因此有时候也叫 MAC 层。

第二层:“网际层”或者“网络互连层”(internet layer)也叫网络层,IP 协议就处在这一层。由于 IP 协议定义了“IP 地址”的概念,因此就能够在“连接层”的基础上,用 IP 地址取代 MAC 地址,把许许多多的局域网、广域网链接成一个虚拟的巨大网络,在这个网络里找设备时只要把 IP 地址再“翻译”成 MAC 地址就能够了。

第三层:传输层”(transport layer),这个层次协议的职责是保证数据在 IP 地址标记的两点之间“可靠”地传输,是 TCP 协议工做的层次,另外还有它的一个“小伙伴”UDP。

第四层叫“应用层”(application layer),因为下面的三层把基础打得很是好,因此在这一层就“百花齐放”了,有各类面向具体应用的协议。例如 Telnet、SSH、FTP、SMTP 等等,固然还有咱们的 HTTP。

TCP/IP工做方式

  HTTP 协议的传输过程就是经过协议栈逐层向下,每一层都添加本层的专有数据,层层打包,而后经过下层发送出去。

接收数据则是相反的操做,从下往上穿过协议栈,逐层拆包,每层去掉本层的专有头,上层就会拿到本身的数据。

简单的理解就是相似发快递的过程,快递员从你那拿到包裹,拿到地址,装到他的车子,运送到站点,在分类打包,送去各个物流中转站,到达以后,对方再依次拆包,拿到你寄送过去的物品。

TCP/IP四层与OSI七层模型

  TCP/IP 发明于 1970 年代,当时除了它还有不少其余的网络协议,整个网络世界比较混乱。

这个时候国际标准组织(ISO)注意到了这种现象,就想要来个“大一统”。因而设计出了一个新的网络分层模型,想用这个新框架来统一既存的各类网络协议。TCP/IP 等协议已经在许多网络上实际运行,再推翻重来是不可能的。

因此,OSI 分层模型在发布的时候就明确地代表是一个“参考”,不是强制标准

第一层:物理层,TCP/IP 里无对应;

第二层:数据链路层,对应 TCP/IP 的连接层;

第三层:网络层,对应 TCP/IP 的网际层;

第四层:传输层,对应 TCP/IP 的传输层;

第5、6、七层:统一对应到 TCP/IP 的应用层。

HTTP 链接管理

  目前主流版本http1.1 中的链接管理是会存在对头阻塞的问题,因此性能是存在一点问题的,这个后面在说。

短链接

  HTTP 协议最初(0.9/1.0)是个很是简单的协议,通讯过程也采用了简单的“请求 - 应答”方式。

  它底层的数据传输基于 TCP/IP,每次发送请求前须要先与服务器创建链接,收到响应报文后会当即关闭链接。

  由于客户端与服务器的整个链接过程很短暂,不会与服务器保持长时间的链接状态,因此就被称为“短链接”(short-lived connections)。早期的 HTTP 协议也被称为是“无链接”的协议。

  短链接的缺点至关严重,由于在 TCP 协议里,创建链接和关闭链接都是很是“昂贵”的操做。TCP 创建链接要有“三次握手”,发送 3 个数据包;关闭链接是“四次挥手”,4 个数据包须要 。

长链接

  针对短链接暴露出的缺点,HTTP 协议就提出了“长链接”的通讯方式,也叫“持久链接”

  其实解决办法也很简单,用的就是“成本均摊”的思路,既然 TCP 的链接和关闭很是耗时间,那么就把这个时间成本由原来的一个“请求 - 应答”均摊到多个“请求 - 应答”上。

链接相关的头部字段

  因为长链接对性能的改善效果很是显著,因此在 HTTP/1.1 中的链接都会默认启用长链接。不须要用什么特殊的头字段指定,只要向服务器发送了第一次请求,后续的请求都会重复利用第一次打开的 TCP 链接,也就是长链接,在这个链接上收发数据。

  也能够在请求头里明确地要求使用长链接机制,使用的字段是 Connection,值是“keep-alive”,如图:

长链接缺点

  由于 TCP 链接长时间不关闭,服务器必须在内存里保存它的状态,这就占用了服务器的资源。若是有大量的空闲长链接只连不发,就会很快耗尽服务器的资源,致使服务器没法为真正有须要的用户提供服务。

因此,长链接也须要在恰当的时间关闭,不能永远保持与服务器的链接,这在客户端或者服务器均可以作到。

  在客户端,能够在请求头里加上“Connection: close”字段,告诉服务器:“此次通讯后就关闭链接”。服务器看到这个字段,就知道客户端要主动关闭链接,因而在响应报文里也加上这个字段,发送以后就调用 Socket API 关闭 TCP 链接。

  服务器端一般不会主动关闭链接,但也可使用一些策略。拿 Nginx 来举例,它有两种方式:

  1. 使用keepalive_timeout指令,设置长链接的超时时间,若是在一段时间内链接上没有任何数据收发就主动断开链接,避免空闲链接占用系统资源。
  2. 使用keepalive_requests指令,设置长链接上可发送的最大请求次数。好比设置成 1000,那么当 Nginx 在这个链接上处理了 1000 个请求后,也会主动断开链接。

HTTP 缓存控制

  http 的缓存是经过Cache-Control 字段来控制

  1. max-age:是 HTTP 缓存控制最经常使用的属性,max-age=30”就是资源的有效时间,至关于告诉浏览器,“这个页面只能缓存 30 秒,以后就算是过时,不能用,这也就是常常说的强缓存
  2. no-store:不容许缓存,用于某些变化很是频繁的数据,例如秒杀页面;
  1. no-cache:它的字面含义容易与 no-store 搞混,实际的意思并非不容许缓存,而是能够缓存,但在使用以前必需要去服务器验证是否过时,是否有最新的版本,这也就是常常说的协商缓存
  2. must-revalidate:又是一个和 no-cache 类似的词,它的意思是若是缓存不过时就能够继续使用,但过时了若是还想用就必须去服务器验证。
不止服务器能够设置“Cache-Control”头,浏览器也能够设置“Cache-Control”,也就是说请求 - 应答的双方均可以用这个字段进行缓存控制,互相协商缓存的使用策略。
 

强缓存

  强缓存两个相关的字段是Expires、Cache-ControlHTTP1.0版本使用的是Expires,HTTP1.1使用的是Cache-Control,当这两个字段同时在头部字段中出现时已Cache-Control 为准。

协商缓存

  当 Cache-Control 的值是 no-cache、max-age=0、must-revalidate 中的任意一个时,表示客户端能够缓存资源,可是每次使用缓存资源前都必须从新验证是否须要从新获取资源。
 
条件请求

  HTTP 协议定义了一系列“If”开头的“条件请求”字段,专门用来检查验证资源是否过时,把两个请求才能完成的工做合并在一个请求里作。并且,验证的责任也交给服务器,浏览器只需等待验证的结果。

咱们最经常使用的字段时if-Modified-SinceIf-None-Match这两个。

  在第一次的响应报文里提供Last-modifiedETag,而后第二次请求时就能够带上缓存里的原值,验证资源是不是最新的。若是资源没有变,服务器就回应一个“304 Not Modified”,表示缓存依然有效,浏览器就能够更新一下有效期,而后放心大胆地使用缓存了。

  • if-Modified-Since:上一次响应头里的Last-modified
  • If-None-Match:上一次响应头里的ETag
若是资源没有变,服务器就回应一个“304 Not Modified”,表示缓存依然有效,浏览器就能够更新一下有效期,而后放心大胆地使用缓存了。

ETag

  ETag是服务器根据当前文件的内容,对文件生成惟一的标识,好比MD5算法,只要里面的内容有改动,这个值就会修改,服务器经过把响应头把该字段发送给浏览器。

  浏览器接受到ETag值,会在下次请求的时候,将这个值做为If-None-Match这个字段的内容,发给服务器。

  服务器接收到If-None-Match后,会跟服务器上该资源的ETag进行比对

  • 若是二者同样的话,直接返回304,告诉浏览器直接使用缓存
  • 若是不同的话,说明内容更新了,返回新的资源,跟常规的HTTP请求响应的流程同样

Etag 通常由web 应用服务器生成,根据修改时间、内容大小等生成一个字符串,能够理解为经过某种算法生成 如MD5; 好比

nginxetag 由响应头的 Last-ModifiedContent-Length 表示为十六进制组合而成,不一样的web 服务器采用的算法应该不同;

etag 还分强、弱,一般都是采用弱etag,强etag 耗时间,消耗资源,具体的能够查阅相关资料;

 
 
下篇在继续说说https、http二、对头阻塞、websocket等相关内容
 

参考

透视HTTP协议 ---------Chrono