http基础了解

超文本传输协议(HTTP)是一个用于传输超媒体文档(例如 HTML)的应用层协议。它是为 Web 浏览器与 Web 服务器之间的通信而设计的,但也可以用于其他目的。HTTP 遵循经典的客户端—服务端模型,客户端打开一个连接以发出请求,然后等待直到收到服务器端响应。HTTP 是无状态协议,这意味着服务器不会在两个请求之间保留任何数据(状态)。

版本

1. http/0.9—单行协议

最初版本的 HTTP 协议并没有版本号,后来它的版本号被定位在 0.9 以区分后来的版本。HTTP/0.9 极其简单:请求由单行指令构成,以唯一可用方法 GET 开头,其后跟目标资源的路径(一旦连接到服务器,协议、服务器、端口号这些都不是必须的)。

2. http/1.0—构建可拓展性

由于 HTTP/0.9 协议的应用十分有限,浏览器和服务器迅速扩展内容使其用途更广:

  • 协议版本信息现在会随着每个请求发送(HTTP/1.0 被追加到了 GET 行)。
  • 状态码会在响应开始时发送,使浏览器能了解请求执行成功或失败,并相应调整行为(如更新或使用本地缓存)。
  • 引入了 HTTP 标头的概念,无论是对于请求还是响应,允许传输元数据,使协议变得非常灵活,更具扩展性。
  • 在新 HTTP 标头的帮助下,具备了传输除纯文本 HTML 文件以外其他类型文档的能力(Content-Type)

3. http/1.1—标准化协议

HTTP/1.1 消除了大量歧义内容并引入了多项改进:

  • 连接可以复用,节省了多次打开 TCP 连接加载网页文档资源的时间。
  • 增加管线化技术,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。
  • 支持响应分块。
  • 引入额外的缓存控制机制。
  • 引入内容协商机制,包括语言、编码、类型等。并允许客户端和服务器之间约定以最合适的内容进行交换。
  • 凭借 Host 标头,能够使不同域名配置在同一个 IP 地址的服务器上。

4. http/2

HTTP/2 在 HTTP/1.1 有几处基本的不同:

  • HTTP/2 是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。
  • 这是一个多路复用协议。并行的请求能在同一个链接中处理,移除了 HTTP/1.x 中顺序和阻塞的约束。
  • 压缩了标头。因为标头在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
  • 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。
  • 对 Alt-Svc 的支持允许了给定资源的位置和资源鉴定,允许了更智能的 CDN 缓冲机制。
  • 客户端提示(client hint)的引入允许浏览器或者客户端来主动交流它的需求,或者是硬件约束的信息给服务端。
  • 在 Cookie 标头中引入安全相关的前缀,现在帮助保证一个安全的 Cookie 没被更改过。

5. http/3—基于QUIC的Http

HTTP 的下一个主要版本,HTTP/3 有着与 HTTP 早期版本的相同语义,但在传输层部分使用 QUIC(en-US) 而不是 TCP。到 2022 年 10 月,26% 的网站正在使用 HTTP/3

QUIC 旨在为 HTTP 连接设计更低的延迟。类似于 HTTP/2,它是一个多路复用协议,但是 HTTP/2 通过单个 TCP 连接运行,所以在 TCP 层处理的数据包丢失检测和重传可以阻止所有流。QUIC 通过 UDP 运行多个流,并为

http/1.x 的连接管理

在 HTTP/1.x 里有多种模型:短连接长连接HTTP 流水线

连接模型,它会保持连接去完成多次连续的请求,减少了不断重新打开连接的时间。然后是 HTTP 流水线模型,它还要更先进一些,多个连续的请求甚至都不用等待立即返回就可以被发送,这样就减少了耗费在网络延迟上的时间(疑问:丢包的可能性是否变大)。

HTTP 的连接管理适用于两个连续节点之间的连接,它是逐跳(Hop-by-hop)标头,而不是端到端(End-to-end)标头

1. 短连接

HTTP 最早期的模型和 HTTP/1.0 的默认模型,是短连接。每一个 HTTP 请求都由它自己独立的连接完成;这意味着发起每一个 HTTP 请求之前都会有一次 TCP 握手,而且是连续不断的。

这是 HTTP/1.0 的默认模型(如果没有指定 Connection 协议头,或者是值被设置为 close)。而在 HTTP/1.1 中,只有当 Connection 被设置为 close 时才会用到这个模型。

2. 长连接

一个长连接会保持一段时间,重复用于发送一系列请求,节省了新建 TCP 连接握手的时间,还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着:连接在空闲一段时间后会被关闭(服务器可以使用 Keep-Alive 协议头来指定一个最小的连接保持时间)。

长连接也还是有缺点的;就算是在空闲状态,它还是会消耗服务器资源,而且在重负载时,还有可能遭受 DoS 攻击。这种场景下,可以使用非长连接,即尽快关闭那些空闲的连接,也能对性能有所提升。

HTTP/1.0 里默认并不使用长连接。把 Connection 设置成 close 以外的其他参数都可以让其保持长连接,通常会设置为 retry-after。

在 HTTP/1.1 里,默认就是长连接的,不再需要标头(但我们还是会把它加上,万一某个时候因为某种原因要退回到 HTTP/1.0 呢)。

3. 流水线连接

流水线已被 HTTP/2 中更好的算法——多路复用(multiplexing)所取代。

默认情况下,HTTP 请求是按顺序发出的。下一个请求只有在当前请求收到响应过后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。

流水线是在同一条长连接上发出连续的请求,而不用等待应答返回。这样可以避免连接延迟。理论上讲,性能还会因为两个 HTTP 请求有可能被打包到一个 TCP 消息包中而得到提升。就算 HTTP 请求不断的继续,尺寸会增加,但设置 TCP 的最大分段大小(MSS)选项,仍然足够包含一系列简单的请求。

并不是所有类型的 HTTP 请求都能用到流水线:只有幂等方式,比如 GETHEADPUTDELETE 能够被安全地重试。如果有故障发生时,流水线的内容要能被轻易的重试。

今天,所有遵循 HTTP/1.1 标准的代理和服务器都应该支持流水线,虽然实际情况中还是有很多限制:一个很重要的原因是,目前没有现代浏览器默认启用这个特性。

协议升级

http/2.0不允许使用该机制,该机制仅提供http/1.1使用

HTTP/1.1 协议提供了一种使用 Upgrade(en-US) 标头字段的特殊机制,这一机制允许将一个已建立的连接升级成新的、不相容的协议。

因为 Upgrade 是一个逐跳(Hop-by-hop)标头,它还需要在 Connection 标头字段中列出。这意味着包含 Upgrade 的典型请求类似于:

GET /index.html HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: example/1, foo/2

至今为止,最经常会需要升级一个 HTTP 连接的场合就是使用 WebSocket,它总是通过升级 HTTP 或 HTTPS 连接来实现,手动升级协议的请求类似于:

Connection: Upgrade
Upgrade: websocket

在WebStocket升级中,除了以上必须出现的标头外,还有一些可选标头,提供其他功能

标头

含义

Sec-WebSocket-Extension

用于指定一个或多个请求服务器使用的协议级 WebSocket 扩展

Sec-WebSocket_Key

该标头向服务器提供确认客户端有权请求升级到 WebSocket 的所需信息

Sec-WebSocket-Protocol

按优先顺序指定你希望用的一个或者多个 WebSocket 协议

Sec-WebSocket-Version

指定客户端希望使用的 WebSocket 协议版本,以便服务器可以确认其是否支持该版本。

http身份验证

HTTP 提供一个用于权限控制和认证的通用框架。服务器可以用来质询(challenge)客户端的请求,客户端则可以提供身份验证凭据。

认证方式

http认证方式有多种,以下介绍我认为比较需要了解的三种,basic身份验证、session验证、token验证

basic身份验证

basic这种身份验证,就相当于你去一些地方,它只认你的身份证,你必须每次携带身份证,然后它在后台验证你是你之后,你才可以进去。

这种认证方法的优点是简单,容易理解。

缺点有:

  • 不安全:认证身份信息用明文传送,因此需结合 https 使用。
  • 效率低:服务端处理请求时,每次都需要验证身份信息,如用户名和密码。

大致的流程理解如下:

  1. 客户端向浏览器发起如下请求,其中protected_docs是一个受限制的资源
GET/ protected_docs HTTP/1.1
  1. 服务端发现该资源受限,给客户端返回401,要求验证其身份(对于代理来说,响应的状态码是407)
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm=protected_docs //用户
Proxy-Authenticate: Basic realm=protected_docs //代理

响应首部中,通过WWW-Authenticate或者Proxy-Authenticate告知客户端,认证的方案是Basic。同时以realm告知认证的范围。

  1. 客户端进行用户名以及密码的登录(证明用户代理身份的凭据)

Authorization请求首部中,包含了用户填写的用户名、密码。

GET /protected_docs HTTP/1.1
Authorization: *** Y2h5aW5ncDoxMjM0NTY=
Proxy-Authorization: *** Y2h5aW5ncDoxMjM0NTY=
  1. 服务端再次验证请求

服务端收到用户的认证请求后,对请求进行验证。验证包含如下步骤:

  1. 根据用户请求资源的地址,确定资源对应的realm。
  2. 解析 Authorization 请求首部,获得用户名、密码。
  3. 判断用户是否有访问该realm的权限。
  4. 验证用户名、密码是否匹配。

一旦上述验证通过,则返回请求资源。如果验证失败,则返回401要求重新认证,或者返回403(Forbidden)。

session验证

session验证这种方法,可以理解为你有身份证,但是不需要随时携带,到达某些地方只需要报身份证号,然后后台就可以验证

优点:

  • 较安全:客户端每次请求时无需发送身份信息,只需发送 SessionID。
  • 较高效:服务端无需每次处理请求时都要验证身份信息,只需通过 SessionID 查询 Session 对象。

缺点:

  • 扩展性差,Session 对象保存在服务端,如果是保存在多个服务器上,有一致性问题,如果保存在单个服务器上,无法适应用户增长。
  • 基于 Cookie 的 SessionID 不能跨域共享,同一用户的多个客户端(如浏览器客户端和 APP)不能共享 SessionId。
  • 基于 Cookie 的 SessionID 易被截获生成 CSRF 攻击。
  • 其交互过程如下:
  1. 客户端在登录页面输入身份信息,如用户名/密码。
  2. 服务端验证身份信息,通过后生成一个 Session 对象,保存到服务端,并将 SessionID 值以 Cookie 形式返回给客户端。
  3. 客户端将接收到的 SessionID 保存到 Cookie 中,并且之后每次请求都在请求头中携带 SessionID Cookie。
  4. 服务端从请求的 Cookie 中获取 SessionID,并查询其对应的 Session 对象,从而获得身份信息。
  5. 客户端退出本次会话后,客户端删除 SessionID 的 Cookie,服务端删除 Session 对象。
  6. 如果客户端之后要重新登录,需重新生成 Session 对象和 SessionID。

token验证

token认证就相当于你去公司上班,公司给你发了一个工牌,你进入公司只需要出示工牌,但是并不需要查你的信息。

是一种 SPA 应用和 APP 经常使用的认证方法。它是一种无状态的认证方法。

客户端首先将用户信息发送给服务端,服务端根据用户信息+私钥生成一个唯一的 Token 并返回给客户端。Token 只保存在客户端,之后客户端的每个请求头中都携带 Token,而服务端只通过运算(无需查询)来验证用户。

大致的流程理解如下:

  1. 客户端向浏览器发出发起请求,请求一个受限制的资源
GET/ protected_docs HTTP/1.1
  1. 服务端发现该资源受限,给客户端返回401,要求验证其身份
HTTP/1.1 401 Unauthorized
WWW-Authenticate: token 
  1. 客户端发送token验证给服务端
GET /protected_docs HTTP/1.1
Authorization: token fe23hbihio2jnuoxcds
  1. 服务端对token进行运算

cookie

HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器——如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

但现在推荐使用现代存储 API

创建cookie

服务器收到 HTTP 请求后,服务器可以在响应标头里面添加一个或多个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,并将其放在 HTTP Cookie 标头内,向同一服务器发出请求时一起发送。你可以指定一个过期日期或者时间段之后,不能发送 cookie

Set-Cookie: <cookie-name>=<cookie-value>

cookie生命周期

Cookie 的生命周期可以通过两种方式定义:

  • 会话期 Cookie 会在当前的会话结束之后删除。浏览器定义了“当前会话”结束的时间,一些浏览器重启时会使用会话恢复。这可能导致会话 cookie 无限延长。
  • 持久性 Cookie 在过期时间(Expires)指定的日期或有效期(Max-Age)指定的一段时间后被删除。

cookie安全

有两种方法可以确保 Cookie 被安全发送,并且不会被意外的参与者或脚本访问:Secure 属性和 HttpOnly 属性。

标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端。它永远不会使用不安全的 HTTP 发送(本地主机除外),这意味着中间人攻击者无法轻松访问它。不安全的站点(在 URL 中带有 http:)无法使用 Secure 属性设置 cookie。但是,Secure 不会阻止对 cookie 中敏感信息的访问。例如,有权访问客户端硬盘(或,如果未设置 HttpOnly 属性,则为 JavaScript)的人可以读取和修改它。

JavaScript Document.cookie API 无法访问带有 HttpOnly 属性的 cookie;此类 Cookie 仅作用于服务器。例如,持久化服务器端会话的 Cookie 不需要对 JavaScript 可用,而应具有 HttpOnly 属性。此预防措施有助于缓解跨站点脚本(XSS)攻击。

cookie发送的位置

Domain 和 Path 标识定义了 Cookie 的作用域:即允许 Cookie 应该发送给哪些 URL。

Domain 指定了哪些主机可以接受 Cookie。如果不指定,该属性默认为同一 host 设置 cookie,不包含子域名。如果指定了 Domain,则一般包含子域名

Path 属性指定了一个 URL 路径,该 URL 路径必须存在于请求的 URL 中,以便发送 Cookie 标头。以字符 %x2F (“/”) 作为路径分隔符,并且子路径也会被匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值