应用层
字数: 0
Application Layer: 考虑怎样在网络应用程序和用户之间通信

应用架构

客户-服务器方式

C/S, Client/Server
有专门的服务器提供服务,客户端发起请求以获取服务。服务器是中心节点,负责处理来自多个客户端的请求。
中心化
中心化

对等方式

P2P, Peer-to-Peer
每个节点既是客户端又是服务器。节点之间直接交换资源和服务,没有中心节点。
分布式
分布式

Email

发送协议

SMTP

Simple Mail Transfer Protocol
User agent: Allow users to read, reply to, forward, save, and compose, edit messages
  • Example: Microsoft Outlook
Mail server: Store outgoing and incoming messages
  • Example: Microsoft Exchange
notion image

接收协议

POP3

Post Office Protocol—Version 3

IMAP

Internet Mail Access Protocol
notion image

HTTP

依赖于 TCP 和 UDP 协议
Hyper Text Transfer Protocol specifies communication of browser and server
notion image
HTTP 是不加密的
它以明文形式发送数据。即传输的所有内容,包括 URL、头信息、以及内容本身,可以被网络上任何可以访问数据传输路径的节点轻易读取或修改。例如,网络中间人(网络提供商、路由器、代理服务器)可以看到你的请求内容和响应内容。

HTTP 版本

HTTP 1.0

早期 Web 的基础协议,使用短连接 (Non-persistent HTTP),每次交互都需要新建立连接,无法有效复用连接,导致额外的延迟和资源消耗。→ 每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。
🤐
没有标准的压缩方法规定

  • at most one object sent over one TCP connection, then closed
  • download multiple objects required multiple conections
notion image
notion image
  • RTT (round-trip time): time for a small packet to travel from client to server and back
  • one RTT to initiate TCP connection
  • one RTT for HTTP request (for Web pages from Web server) and firstt few bytes of HTTP responsee to return

HTTP 1.1

引入长连接(Persistent HTTP),允许在一个连接上发送多个请求和响应,减少了建立和关闭连接的开销。
  • 引入 PUT / DELETE 方法
  • 引入 Cache-Control / ETag / Last-Modified 头部进行缓存(见下文 📦)
🤐
常用的压缩方法是 gzip 和 deflate
 
notion image

HTTP 2.0

notion image
  • 二进制分帧层,将所有传输的信息分割为更小的消息和帧
    • 文本形式传输,易于阅读和调试,但通常会较大
    • 二进制格式传输,减少了带宽消耗和传输时间,有更快的解析速度
  • 支持多路复用,允许在单一连接上并行地发送多个请求和响应,减少延迟
    • 即使用一个 TCP 连接来处理多个 HTTP 请求和响应,这意味着不同的模块(如页面上的不同资源:HTML、CSS、JavaScript、图片等)可以通过同一个连接同时传输,而不需要为每个模块建立单独的连接。
      • Webpack 按顺序发出这些块。浏览器可以在等待下载最新文件的同时开始执行缓存中的文件。当使用代码分割进行按需加载时,Webpack 会并行请求。
    • 引入服务器推送功能,服务器可以主动向客户端发送资源,不必等待请求
      • 可用于将包拆分为多个较小的块存入缓存,然后在请求 HTML 页面时将不同的 chunk 主动发送到客户端。
    • 流量控制
    • 首部压缩
      • 🤐
        HPACK 压缩方法
        1. 静态字典 (Static Table):包含了一组预定义的常见 HTTP 头部键值对,在压缩和解压缩过程中用于对常见头部进行编码和解码,从而减少传输的开销。
        1. 动态字典 (Dynamic Table):动态字典是在 HTTP/2 通信过程中动态构建的,它存储了最近使用过的 HTTP 头部键值对。动态字典可以根据通信过程中的实际需要进行更新和调整,以适应不同的场景和请求。

    HTTP 3.0

    使用基于 UDP 的 QUIC (Quick Udp Internet Connection) 协议作为传输层协议 → 解决了头部阻塞问题,允许请求和响应的头部信息在数据流中独立传输。
    • 相较于 TCP,QUIC 具有更低的连接建立延迟和更好的拥塞控制
    notion image

    Header

    通用头部

    • Content-Type:请求体的媒体类型,如 text/htmlapplication/json
    • Content-Length:请求体或响应体的大小(字节)
    • Cache-Control:指定请求和响应遵循的缓存机制
    • Connection:控制是否保持网络连接开启或关闭
    • Date:消息发送的日期和时间

    请求头部

    • Accept:客户端能够接收的内容类型
    • Accept-Language:客户端能够理解的自然语言列表
    • User-Agent:发起请求的客户端应用信息
    • Host:请求发送的目标服务器地址
    • Authorization:认证信息,如 Token
    • Cookie:服务器发送到客户端的 Cookie
    • Referer:引发请求的原始资源地址

    响应头部

    • Set-Cookie:服务器发送到客户端的 cookie
    • ETag:资源的特定版本标识,用于缓存控制
    • Expires:资源过期的日期时间
    • Last-Modified:资源最后修改的日期时间
    • Server:服务器软件信息。
    • WWW-Authenticate:客户端适用的认证方案和参数

    实体头部

    • Content-Encoding:实体数据应用的编码方式,如 gzip
    • Content-Language:实体数据的自然语言
    • Content-Location:请求资源可替代的备用位置

    缓存机制

    强缓存

    Strong Cache
    使用场景 → 不经常更新的静态资源 (图片/ CSS / JS) 文件。同时可以配合修改版本号(app.v1.js) 来触发新的下载。
    通过设置 HTTP 响应头实现,主要包括以下两个响应头:
    1. Cache-Control
        • public:表示响应可以被任何缓存(包括浏览器缓存和 CDN)缓存。
        • private:表示响应只能被客户端(浏览器)缓存。
          • 对于 GET 请求的响应,默认是 public 的,而对于其他类型的请求(如 POST),则是 private 的。
        • max-age:指定资源在缓存中的最大有效时间,以秒为单位。
          • 🕳️
            存在问题
            • 静态资源更新:如果资源在服务器上更新了,但 max-age 尚未过期,用户可能仍然得到旧版本的资源,因为浏览器不会去服务器检查新版本。
            • 缓存管理:过度依赖 max-age 可能导致缓存存储迅速增长,需要更细致的缓存策略来避免不必要的缓存占用。
        • no-cache:表示缓存需要向服务器验证资源是否过期,但仍然可以缓存。
        • no-store:表示不缓存响应的任何部分,始终从服务器获取最新的资源。
    1. Expires:指定资源的过期时间
    当客户端发送请求时,如果发现响应中包含了强缓存相关的响应头,并且缓存未过期,则客户端可以直接使用缓存的资源,而无需向服务器发起请求。

    协商缓存

    Conditional Cache / Negotiated Cache
    通过与服务器进行通信来验证资源是否仍然有效 → 主要针对频繁变动的资源,例如 API 请求结果(动态内容与用户个性化设置),这些内容可能经常发生变化,但不一定每次都需要重新下载。
    首先设置 Cache-Control: no-cache ,然后配合以下两种响应头实现
    1. Last-Modified:服务器在响应中发送资源的最后修改时间。
      1. 优点
          • 使用的是时间戳,精度通常可以达到秒级,服务器可以比较容易地获取资源的最后修改时间。
          • 是 HTTP/1.0 规范中定义的标准字段,与 HTTP/1.0 兼容的服务器和客户端可以支持它。
      2. 缺点
          • 时间戳的精度有限,当两次修改在1秒内时,无法检测到变化。
          • 如果服务器的时间与客户端的时间不同步,可能会导致问题。
    1. ETag:服务器在响应中发送资源的唯一标识符(通常是哈希值)。
      1. 优点
          • 服务器生成的唯一标识符,通常基于资源内容的哈希值或其他算法生成。客户端在请求资源时,可以将上次获取到的 ETag 值发送给服务器,服务器收到后会检查资源是否与该 ETag 值匹配。如果资源没有发生变化,服务器将返回状态码 304(Not Modified),告诉客户端可以继续使用缓存的资源,否则服务器将返回新的资源内容。
          • 可以更精确地判断资源是否发生了变化。
          • HTTP/1.1 规范中定义的标准字段,更现代的应用通常会优先使用它。
      2. 缺点
          • 生成和比较 ETag 会消耗一些服务器资源,尤其对于大文件或高流量网站。
          • 一些代理服务器或 CDN 可能不支持 ETag,可能会导致不稳定的缓存效果。
    当客户端发送请求时,如果发现响应中包含了协商缓存相关的响应头,客户端会将上一次请求中的
    • If-Modified-Since(对应 Last-Modified
    • If-None-Match(对应 ETag
    请求头发送给服务器,服务器根据这些值判断资源是否发生了变化。如果资源没有变化,则返回 304 Not Modified 响应,客户端继续使用缓存的资源
    优先级上 ETag 更高,因为它可以更精确地判断资源是否变化。

    请求方法

    GET

    使用 URL 查询字符串来传输数据→ 请求用于检索数据
    • GET 请求的结果可以在一段时间内被缓存起来(包括浏览器/客户端/代理服务器等),便于未来的相同请求可以快速地获取响应
    notion image
    notion image

    POST

    将数据包含在 HTTP 请求的消息体中 → 请求涉及数据修改时,如提交表单、上传文件
    • 默认情况下不会被浏览器缓存,每次发送 POST 请求都会获取新的响应
    notion image
    notion image
    哪个刷新会丢失数据?
    刷新页面时,GET 请求会重新发送相同的请求,而 POST 请求会弹出一个确认框,询问用户是否要重新提交表单数据。这意味着刷新页面时,POST 请求可能会导致数据的重复提交,可能会丢失数据。

    PUT / DELETE

    • PUT 用于创建或更新资源,DELETE 于删除资源。
    • 它们的引入主要用于 RESTful 架构,增强资源操作清晰度,提升 API 设计质量。

    状态码

    notion image
    notion image

    2xx

    • 200:OK
    201:Created
    通常在 POST 请求中使用,当服务器成功创建了一个新资源时。
    202:Accepted
    请求已接受,但尚未处理。
    • 例如,异步处理任务。
    203:Non-Authoritative Information
    请求成功,但返回的信息可能不是来自原始服务器。
    • 通常在代理服务器使用时会出现这种情况。
    204:No Content
    请求成功,但没有返回内容。
    • 通常用于 DELETE 请求,表示删除操作成功但没有返回任何数据。

    3XX

    301:Moved Permanently
    • 用户访问 example.com/old-page 时,服务器响应并重定向 example.com/new-page 后,未来的请求会直接访问 new-page
      • 即 old 链接已经没有存在的意义了,它所有的价值都会导向给 new。对于搜索引擎来说 new 链接现在就是 old 链接了。所以 old 链接的权重会直接传给 new 链接。这就是常说的 301 对 SEO 有好处的原因。
      •  301 是谷歌官方认为将网站地址由 HTTP 迁移到 HTTPS 的最佳方法。
    302:Moved Temporarily
    • 最常见的一种重定向方法,但同时也是现实与标准相矛盾的典型案例。在HTTP/1.1 中修改为 Found
    • 未来的请求仍然会访问 old-page
      • 📌
        虽然规范中不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器使用 GET 方式访问在 Location中规定的 URI,而无视原先请求的方法。因此状态码 303 和 307 被添加了进来,用以明确服务器期待客户端进行何种反应。
        • 即 一般情况下都会实现为 GET 的重定向,但是不能确保 POST 会重定向为 POST。
        • 302 似乎包含了 303 的情况 → 这是由历史原因导致的
    303:See Other
    • 即无论原请求是 GET 还是 POST,客户端收到服务端的响应后,必须使用 GET 方法重定向到新地址。
      •  常用于将 POST 请求重定向到 GET 请求,比如上传了一份个人信息,服务器将你导向一个 “上传成功” 页面。
    • 禁止响应被缓存。
    304:Not Modified
    [协商]缓存重定向,资源未修改,可继续使用之前的内容
    307:Temporary Redirect
    • 与 302 类似,未来的请求仍然会访问 old-page
    • 但是明确要求客户端使用相同的 HTTP 方法进行重定向,即原本使用 POST,重定向依旧是 POST。
    308:Permanent Redirect
    • 与 301 类似,未来的请求直接会访问 new-page
    • 但是明确要求客户端使用相同的 HTTP 方法进行重定向…

    4XX

    • 400:服务器无法理解请求的格式
    • 401:(Unauthorized) 请求未授权,需要身份验证
    • 403:(Forbidden) 服务器理解请求,但拒绝执行。
      • 客户端虽然提供了有效的身份验证凭据,但由于权限限制而失败

    5XX

    • 500:内部服务器错误
    • 504:网关超时,未能及时从上游服务器接收到响应时

    HTTPS

    Hyper Text Transfer Protocol Secure
    HTTPS 是 HTTP 协议通过 (Secure Socket Layer / Transport Layer Security) 加密后的版本。
    • SSL 是 TLS 的前身,可以理解为应用层与传输层之间的独立层。
    notion image
    随便打开一个线上网站,然后利用 Chrome 的开发者工具,可以看到发送了很多 HTTPS 请求,也能看到请求的内容,这难道加密了吗?
    • 当使用浏览器发送 HTTPS 请求时,浏览器首先在内部构建请求信息,包括 URL、头信息和可能的请求体。这时信息是明文的,它还没离开浏览器
    • 在发送到网络之前,浏览器使用与服务器协商的加密算法和密钥加密这些数据。然后,这些加密后的数据被发送到网络。

    加密方式

    (非) 对称加密

    • 握手阶段: 在 SSL/TLS 握手阶段,非对称加密用于安全地交换对称密钥。客户端生成的 Pre-Master Secret 会使用服务器的公钥加密后发送给服务器,服务器使用自己的私钥解密,从而确保了对称密钥的安全传输。
    • 身份验证: 非对称加密也用于服务器的身份验证。服务器会发送自己的数字证书(包含公钥),客户端通过 CA 认证的方式验证证书的合法性,以此确认服务器的身份。
    • 数据传输阶段: 在握手阶段结束后,客户端和服务器生成了一个共享的对称密钥,用于加密后续所有的通信数据。这种方式可以确保通信效率,因为对称加密的计算复杂度较低,适合快速加密和解密大量数据。

    数字证书

    包含一个公钥和与之相关联的私钥,这种非对称加密方法使得只有拥有私钥的人能解密,安全性更高但速度较慢。
    • 证书如何 “防篡改 / 防调包” ?
      • 证书由权威的 CA(证书颁发机构)签名,包含了服务器的公钥、颁发者信息、有效期等。证书一旦被篡改,签名验证就会失败,浏览器会发出警告。
      • SSL / TLS 提供的握手过程,确保中间人无法在不被发现的情况下替换证书。

    连接过程

    🤔
    相当于 TLS 的 四次握手
    1. 客户端发起连接:浏览器(客户端)向服务器发起 HTTPS 请求,给出协议版本号、一个客户端生成的随机数(Random secret),以及客户端支持的加密方法
    1. 服务器响应:服务端确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Premaster secret)
    1. 证书验证:客户端验证数字证书的合法性(是否来自受信任的 CA,是否未过期,并确认与服务器域名匹配)
    1. 密钥交换:客户端生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数,发给服务端
    1. 服务器解密密钥:服务器使用自己的私钥来解密客户端发送的加密密钥(随机数)
    1. 安全通信:双方使用协商好的对称密钥(Session key,由前面的三个随机数生成)在加密通道中传输数据
    notion image

    DNS

    依赖于 TCP 和 UDP 协议
    Domain name system is a directory service that provides a mapping between the name of a host on the network and its IP address.
    • 计算机既可以被赋予 IP 地址,也可以被赋予主机名和域名。
    • 用户通常使用主机名或域名来访问对方的计算机,而不是直接通过 IP 地址访问。
    DNS 域名解析,输入和输出是什么?
    • 输入:用户输入的域名(如 www.example.com
    • 输出:与该域名对应的 IP 地址

    解析过程

    首先操作系统会检查本地缓存中是否有这个域名对应的 IP 地址,如果有,直接使用。如果本地缓存没有找到,系统会查看本地的 hosts 文件,看看是否有相关记录。
    如果以上均没有找到,系统会向本地配置的 DNS 服务器(通常是 ISP 提供的)发送 DNS 查询请求。

    递归查询

    → 大多数客户端(如个人电脑、智能手机等)
    客户端将查询请求发送给一个 DNS 服务器,如果这个 DNS 服务器不直接拥有请求的记录,它将代表客户端向其他 DNS 服务器查询,直到找到答案。

    迭代查询

    → 大多数公共 DNS 服务器和 ISP 的DNS服务器
    客户端向 DNS 服务器发送查询请求,如果服务器没有答案,它不会代表客户端进行查询,而是返回一个对客户端有帮助的 “最佳” DNS 服务器地址。

    记录类型

    notion image

    URL

    Uniform Resource locator serves as system for resources on web
    notion image
    当在浏览器中输入一个 URL 后,会发生什么?
    1. 解析 URL:游览器根据 URL 中的协议、域名、资源路径来确定要请求的资源
    1. 域名解析:为了找到服务器的 IP 地址,浏览器需要进行 DNS 查询。
      1. 如果域名的 IP 地址未缓存在浏览器或操作系统的 DNS 缓存中,浏览器会向配置的 DNS 服务器发起查询。
      2. 这个查询可能是递归的,也可能是迭代的,直到找到域名对应的IP地址。
    1. 建立 TCP 连接:浏览器使用 HTTP (端口 80) 或 HTTPS (端口 443) 协议与服务器建立 TCP 连接。
        • 如果使用 HTTPS,会涉及 SSL/TLS 握手建立安全连接 → 展开(HTTPS连接过程)
    1. 发送请求:浏览器构建一个HTTP(或HTTPS)请求。请求包括 HTTP 方法(例如 GET、POST)、请求头(例如 User-Agent、Accept)、请求体(对于 POST 请求)等信息。
    1. 服务器处理请求并响应:根据请求的内容和路由,执行相应的处理,例如查询数据库、处理业务逻辑等,并生成一个响应消息。这个响应包括了状态码(如 200 表示成功),可能的响应头信息,以及请求的资源内容。
    1. 浏览器渲染页面:构建 DOM 树

    CDN

    代理

    Client → Proxy → Server
    🔑
    为什么要代理?直接请求源服务器不行吗?
    • 隐私和安全性
    • 性能和负载均衡
    相当于中间商,本来 A 和 B 可以直接连接,但是此时添加了一个 C 在中间。
    A 跟 B 不直接连接,而是通过 C 作为中介进行连接。
    最常见的例子就是二手房东,租房子时签约的人不是房子的真正房东,而是房东委托的中介,房东不想管事,所以才会通过中介(代理)进行处理。

    正向代理

    Forward Proxy,为了隐藏客户端身份
    顺着请求方向进行的代理,即代理服务器它是由你配置,去请求目标服务器地址。
    • 访问原来无法访问的资源,如 Google → VPN
    • 可以做缓存,加速访问资源

    反向代理

    Reverse Proxy,为了隐藏服务端身份
    比如访问百度,其代理服务器对外的域名为 https://www.baidu.com。具体内部的服务器节点我们不知道。现实中通过访问百度的代理服务器后,代理服务器将请求转发到它们 多的服务器节点中,然后进行搜索后将结果返回。
    • 负载均衡 → Nginx

    🔯
    CDN 实际上是一种特殊的反向代理,它通过将网站的静态资源缓存在全球多个服务器节点上,加速资源加载,相关流程如下:
    • DNS 查询:解析会返回 CDN 的节点 IP 地址,而不是源服务器的 IP 地址。
    • 请求路由:如果请求的资源已经在 CDN 节点的缓存中,会直接返回资源。
    • 缓存资源 / 缓存更新:根据设定的缓存策略(例如过期时间)来管理。
    用了CDN 最后包的总体积不也是一样大吗?为什么这样可以优化?
    • 减少网络延迟:用户可以从离自己「地理位置最近」的服务器获取资源
    • 提高稳定性:如果一个服务器出现故障,会将请求重定向到其他可用的服务器
    • 节省带宽成本:使用「缓存机制」,减少对源服务器的请求次数
    notion image

    Cookie

    客户端存储服务端数据的一种机制,它是客户端发送给服务器 HTTP 请求上的附加信息。

    常用属性

    Domain:指定 Cookie 可以发送到的域名。
    • 例如,Domain=example.com 允许 Cookie 被发送到 example.com 及其子域sub.example.com
    • 如果不指定 Domain,浏览器默认使用创建 Cookie 时所在的域,即只能在同源 (Same-Origin) 的请求中发送。
    Path:指定 Cookie 可以发送到的 URL 路径。
    • 例如,Path=/test只请求 example.com/test 或其子路径 example.com/test/sub
    • 默认值为 /,即 在整个域名下都有效。
    • Expires
    • Max-Age
    • Secure:仅在 HTTPS 连接中发送。
    • HttpOnly:Cookie 不能被 JavaScript 访问。
    SameSite :用于控制跨站点请求时是否发送 Cookie。
    • Strict :浏览器仅在目标站点的 URL 与请求页面的 URL 完全一致(即同站点)时发送 Cookie,否则不发送。这有助于防止 CSRF。
    • Lax
      • 当通过链接从外部站点访问目标站点时,发送
      • 当从当前浏览器选项卡中导航到目标站点时,发送
      • 当通过 POST 请求进行的(例如表单提交),不发送
    • None

    各种存储手段的大小限制?
    • Cookie:4KB
    • LocalStorage / SessionStorage:5MB
    • IndexedDB大小限制不统一,部分现代浏览器为每个域提供约 50MB 至无上限的存储空间,这取决于用户的硬盘空间和浏览器的具体实现
    携带 Cookie 前提?
    默认情况只有当请求与设置 Cookie 的网站处于同一个源(协议、域名、端口全部相同)时,浏览器才会自动携带 Cookies
    Cookie 在哪种场景下比 localStorage 更好?
    • Cookies 通常用于存储身份验证令牌和进行会话管理,即保持用户登录状态
    • localStorage 数据没有到期时间,适合长期存储,适合存储大量不需要频繁发送到服务器的数据
    Cookie 怎么防止被篡改?
    使用 HTTPS 协议 / 设置 HttpOnly 标志 / 设置 Secure 标志
    使用加密算法 / 使用签名 / 限制 Cookie 的域和路径 / 定期更新 Cookie

    Session

    广义上来说,Session 是服务端存储用户状态的一种机制,不管是用什么存储(各种内存、缓存、数据库),都属于会话。
    狭义上来说,传统的 Session 实现基本是 Cookie-based Session
    notion image

    Token

    本质就是一段字符串,作为验证用户身份的“令牌”。至于怎么生成,具体算法由你选择。
    • 从这个角度, SessionId 也是 Token。只不过前后端分离 / APP 兴起,换了种说法。
    • 不要混淆了 “Session” 与 “Session 的实现”

    JWT

    Json Web Token 通过把用户信息,用密钥加密防止篡改,然后放在请求头里。用户请求的时候再解密,于是服务器就不需要保存用户的信息了。JWT 是无状态的,同时有明显缺点:
    • 无法撤销:一旦被签发,在到期时间之前都是有效的。
      • → 黑名单机制
    • 及时刷新:总不能用户操作一半,突然过期了。
      • → acessToken + refreshToken
    虽然有不同手段能暂时解决问题,但是此时又发现,项目架构又回到了传统 Session 模型中,对 JWT 来讲属于自断招牌。那么属于 JWT 的更合适使用场景是什么?
    • 不应该用于维护用户登陆状态(Authentication)
      • 如果作为访问凭证,那么它面临的问题和普遍意义上的 Session 完全一样,反而增加了复杂度。
    • 可以用于短时间内的授权(Authorization)
      • 临时文件分享链接
      • 第三方应用接入
    2023 - 2026