HTTP实用指南 | 青训营

31 阅读37分钟

一、初识

HTTP(超文本传输协议)是一种用于在计算机网络中传输超文本(即文本、图像、音频、视频等多媒体数据)的协议。它是一种客户端-服务器协议,用于在客户端(例如浏览器)和服务器之间传递信息。HTTP是互联网上最常用的协议之一,用于在Web浏览器和Web服务器之间传递数据,从而实现用户访问网页、发送和接收信息的功能。

HTTP协议的基本工作原理

  1. 客户端发送请求(Request): 当用户在浏览器中输入网址或点击链接时,浏览器会创建一个HTTP请求并发送给服务器。这个请求包含了用户要访问的资源的地址、请求方法(如GET、POST等)、请求头部(包含一些关于请求的信息)以及可选的请求体(用于传递一些数据)。
  2. 服务器处理请求: 服务器接收到客户端发送的请求后,会根据请求的信息和路径来寻找相应的资源。服务器可能需要执行一些处理,例如检索数据、处理表单提交、生成动态内容等。
  3. 服务器发送响应(Response): 服务器根据处理结果生成一个HTTP响应,其中包含了响应状态码(用于指示请求是否成功或失败)、响应头部(包含一些关于响应的信息)以及响应体(包含实际的数据,如HTML文档、图像等)。
  4. 客户端接收响应: 客户端浏览器接收到服务器的响应后,会解析响应内容并根据响应中的数据展示内容给用户。这可能包括在浏览器中显示网页、加载图像、播放音频/视频等。

HTTP协议的基本特点

  1. HTTP是应用层协议,基于TCP协议: HTTP作为应用层协议,在基于TCP的传输层之上,通过客户端和服务器之间的请求和响应模型,实现了在互联网上传输超文本数据的功能。
  2. HTTP是简单可扩展的协议: HTTP(超文本传输协议)被设计为一种简单可扩展的协议,这意味着它在保持核心功能简单的同时,允许通过添加新的特性来扩展其功能。
  3. HTTP是一种无状态协议: 这意味着每个HTTP请求都是独立的,服务器不会保留之前请求的状态信息。为了处理这种无状态特性,通常会使用一些机制,如Cookies和Session来跟踪和维护用户的状态。

二、协议分析

发展历程

  1. HTTP/0.9: 早期的HTTP协议,于1991年发布,非常简单,只支持获取HTML文档,没有请求头和响应头,也没有HTTP版本号。这个版本主要用于在互联网上共享文本信息。
  2. HTTP/1.0: 于1996年发布,引入了很多新特性,如请求头和响应头、状态码、缓存、代理服务器等。这个版本开始支持多种数据格式,并且为Web浏览器和服务器之间的通信提供了更多的灵活性。
  3. HTTP/1.1: 于1999年发布,是HTTP协议的重要升级版本。它引入了持久连接(keep-alive)功能,允许多个请求和响应共享同一个TCP连接,从而减少了连接的开销。此外,HTTP/1.1还引入了管道化(pipelining)功能,允许客户端发送多个请求而无需等待每个请求的响应,以提高性能。
  4. HTTP/2: 于2015年发布,旨在提高性能和效率。HTTP/2引入了多路复用(Multiplexing)功能,允许在同一个连接上同时传输多个请求和响应,从而减少了延迟。它还引入了头部压缩,以减小数据传输的大小。HTTP/2的目标是加速网页加载速度,提高用户体验。
  5. HTTP/3: 基于Google开发的QUIC协议,于2020年正式发布。HTTP/3主要目标是进一步提高连接性能和安全性。它采用了UDP协议而不是TCP来传输数据,并在其上实现了多路复用、头部压缩等功能。这使得HTTP/3在恶劣网络环境下表现更好,同时提供更好的安全性。

报文结构

  1. HTTP/1.1的结构和一些重要特性的详细分析:
  • 请求结构: HTTP/1.1的请求结构由以下几部分组成:

    • 请求行(Request Line): 包含了HTTP方法、请求的URI(Uniform Resource Identifier)以及HTTP版本号。常见的HTTP方法包括GET、POST、PUT、DELETE等。
    • 请求头部(Request Headers): 包含了一系列的键值对,用于描述请求的附加信息。例如,Host头部指定请求的目标服务器,User-Agent头部标识发送请求的客户端类型等。
    • 空行(Blank Line): 空行用于分隔请求头部和请求体,没有实际的内容。
    • 请求体(Request Body): 对于一些HTTP方法(如POST)而言,请求体可以包含传输的数据,比如表单数据、上传的文件等。
  • 响应结构: HTTP/1.1的响应结构由以下几部分组成:

    • 状态行(Status Line): 包含了HTTP版本号、状态码和状态短语。状态码表示了服务器对请求的处理结果,如200表示成功,404表示资源未找到等。
    • 响应头部(Response Headers): 与请求头部类似,响应头部也包含了一系列键值对,用于描述响应的附加信息。例如,Content-Type头部指示响应的数据类型,Server头部标识响应的服务器类型等。
    • 空行(Blank Line): 空行用于分隔响应头部和响应体,没有实际的内容。
    • 响应体(Response Body): 响应体包含了服务器返回的实际数据,比如HTML文档、图像、视频等。
  • 持久连接(Keep-Alive): HTTP/1.1引入了持久连接的概念,允许多个请求和响应共享同一个TCP连接。这样可以减少连接的开销,提高性能。在一个持久连接中,多个请求可以顺序发送到服务器,并且响应可以按照请求的顺序返回给客户端。

  • 管道化(Pipelining): HTTP/1.1支持管道化,允许客户端在发送多个请求后等待一次性接收多个响应。这样可以减少网络延迟,提高效率。然而,由于一些服务器和代理的实现问题,管道化在实际中并没有广泛使用。

  • 缓存控制: HTTP/1.1引入了更灵活的缓存控制机制,通过响应头部的**Cache-Control**字段,服务器可以指示客户端如何缓存响应内容,从而提高性能并减少对服务器的请求。

  • 分块传输编码(Chunked Transfer Encoding): HTTP/1.1引入了分块传输编码,允许服务器将响应数据分成多个块进行传输。这在传输大文件或动态生成的内容时特别有用,可以实时传输数据,而无需等待整个响应生成完成。

  1. 常见的HTTP方法以及其作用:
  • GET: GET方法用于从服务器获取指定资源的数据。客户端发送一个GET请求时,服务器会返回请求的资源数据(如网页内容、图像等)。GET请求是幂等的,多次相同的GET请求应该返回相同的响应,不应该对服务器状态产生影响。
  • POST: POST方法用于向服务器提交数据,通常用于发送表单数据、上传文件等。服务器接收到POST请求后,可能会根据请求的内容进行处理,并返回响应结果。POST请求不是幂等的,多次相同的POST请求可能会对服务器状态产生不同的影响。
  • PUT: PUT方法用于向服务器上传或更新资源。客户端发送PUT请求时,通常会指定一个资源的URI以及要上传或更新的数据,服务器将根据请求来执行相应的操作。
  • DELETE: DELETE方法用于请求服务器删除指定的资源。客户端发送DELETE请求时,服务器将根据请求的URI来删除相应的资源。
  • HEAD: HEAD方法类似于GET方法,但服务器只返回响应头部信息,不返回实际的资源内容。HEAD请求常用于获取资源的元数据或检查资源是否存在。
  • CONNECT: CONNECT方法用于建立一个网络连接,通常用于代理服务器。客户端发送CONNECT请求时,请求的目标服务器会作为隧道来建立连接,用于代理HTTPS等加密通信。
  • OPTIONS: OPTIONS方法用于获取服务器支持的HTTP方法列表以及其他一些服务器相关的信息。客户端可以通过发送OPTIONS请求来了解服务器的功能和配置。
  • TRACE: TRACE方法用于追踪一个请求-响应的路径,通常用于测试和诊断。服务器会将接收到的请求返回给客户端,从而客户端可以查看在请求-响应过程中是否有任何修改或变化。
  • PATCH: PATCH方法用于部分更新资源。类似于PUT,但PATCH请求通常只更新资源的一部分内容,而不是整个资源。
  1. HTTP方法可以分为两个重要的属性:安全(Safe)和幂等(Idempotent)。
  • 安全(Safe): 安全性指的是使用特定的HTTP方法不会改变服务器资源的状态。安全方法只是从服务器获取资源的信息,而不会对资源进行修改。使用安全方法不应该引起服务器状态的变化。常见的安全方法有GET和HEAD。

    • GET: GET方法用于从服务器获取资源的数据,获取数据的操作应该是只读的,不会改变服务器资源。
    • HEAD: HEAD方法类似于GET方法,但只返回响应头部信息,不返回实际的资源内容。它也是安全的,因为不会对服务器资源造成任何改变。
    • OPTIONS: OPTIONS方法用于向服务器查询特定资源支持的HTTP方法列表,服务器将在响应头部的Allow字段中返回支持的方法列表。这使得客户端可以了解服务器对资源的操作支持情况,而不会对服务器上的资源产生实际影响。
  • 幂等(Idempotent): 幂等性指的是对同一资源重复执行特定HTTP方法的结果应该与执行一次的结果相同。如果一个方法是幂等的,那么对于同一个资源,多次执行这个方法会产生相同的结果。这样的方法可以安全地重试,而不会产生意外的副作用。幂等性在处理网络错误、重试以及分布式系统中非常重要。

    • GET: GET方法是幂等的,因为多次获取同一资源的数据不会对服务器资源产生任何影响。
    • HEAD: HEAD方法也是幂等的,因为多次获取相同资源的响应头部信息不会改变服务器资源。
    • OPTIONS: OPTIONS方法是幂等的,多次执行OPTIONS请求对服务器资源不会产生不同的结果。每次执行OPTIONS请求都会返回关于服务器资源的元数据信息,如支持的HTTP方法列表,但不会改变服务器上的资源状态。
    • PUT: PUT方法用于上传或更新资源,是幂等的。如果多次使用PUT方法更新相同资源,最终的结果应该是一样的。
    • DELETE: DELETE方法用于删除资源,也是幂等的。多次删除相同的资源不会产生不同的结果。
  1. HTTP协议中的状态码

HTTP协议中的状态码是一种三位数字的代码,用于表示服务器对请求的处理结果。当客户端发送HTTP请求到服务器时,服务器会根据请求的处理情况生成一个相应的状态码,然后将状态码作为响应的一部分返回给客户端。状态码提供了客户端和服务器之间通信的重要信息,帮助客户端了解请求的结果、错误情况以及下一步的操作。

HTTP状态码可以分为以下五个类别:

  • 信息性响应(Informational Responses): 这些状态码表示请求正在进行处理或需要进一步处理。信息性响应不常用,常见的状态码有:

    • 100 Continue: 服务器已经接收了部分请求,客户端应该继续发送剩余数据。
    • 101 Switching Protocols: 服务器正在切换协议,用于协商不同的通信协议。
  • 成功响应(Successful Responses): 这些状态码表示服务器已经成功处理请求。常见的状态码有:

    • 200 OK: 请求成功,服务器返回所请求的数据。
    • 201 Created: 请求已成功处理,并且在服务器上创建了新的资源。
    • 204 No Content: 请求成功处理,但服务器不需要返回任何数据。
  • 重定向响应(Redirection Responses): 这些状态码表示需要客户端采取额外的操作才能完成请求。常见的状态码有:

    • 301 Moved Permanently: 请求的资源已永久移动到新的URL。
    • 302 Found: 请求的资源临时移动到新的URL。
    • 307 Temporary Redirect: 临时重定向,客户端应继续使用原始的URL。
  • 客户端错误响应(Client Error Responses): 这些状态码表示客户端发送的请求有错误。常见的状态码有:

    • 400 Bad Request: 请求有语法错误或无法被服务器理解。
    • 401 Unauthorized: 请求需要身份验证,客户端没有提供有效的凭据。
    • 403 Forbidden: 请求被服务器理解,但服务器拒绝执行。
  • 服务器错误响应(Server Error Responses): 这些状态码表示服务器在处理请求时发生了错误。常见的状态码有:

    • 500 Internal Server Error: 服务器遇到了意料之外的错误。
    • 502 Bad Gateway: 服务器作为网关或代理,从上游服务器接收到无效的响应。
  1. RESTful API

RESTful API是一种设计风格和架构模式,用于构建网络应用程序的API(应用程序编程接口)。

  1. 常用请求头

HTTP协议中的请求头部(Request Headers)是客户端在发送HTTP请求时包含的一些附加信息,用于告诉服务器关于请求的更多细节。这些请求头部可以影响服务器对请求的处理方式和响应的生成。

  • 常用的HTTP请求头部:

    • Accept: 告诉服务器客户端可以接受的响应数据的类型,格式为Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8。服务器可以根据这个头部来选择合适的响应内容类型。

    • Content-Type: 指定请求体中包含的数据类型,如表单数据、JSON、XML等,格式为Content-Type: application/json。告诉服务器如何解析请求体数据。

    • Cache-Control: 控制缓存行为,格式为Cache-Control: no-cache。告诉服务器是否使用缓存的响应。其中常见的指令有:

      • max-age: max-age指令指定了资源可以被缓存的最大时间,单位为秒。例如, Cache-Control: max-age=3600表示资源可以在客户端缓存一小时。
      • no-cache: no-cache指令表示客户端需要使用缓存,但在使用缓存前需要向服务器验证资源是否仍然有效。
      • no-store: no-store指令表示客户端不应该缓存资源,每次都需要从服务器获取。
    • If-Modified-Since: 当客户端发送一个GET请求时,可以附带这个头部,其中的值是一个日期时间,表示客户端上一次请求该资源的时间。服务器会检查资源的最后修改时间(由Last-Modified响应头部指定),如果该时间在If-Modified-Since的值之后,服务器返回状态码304 Not Modified,表示资源没有发生改变,客户端可以使用本地缓存。

    • Expires: Expires头部指定了资源过期的时间,是一个绝对时间,即在指定时间后客户端需要重新请求资源。服务器返回的响应头部中可以包含Expires,客户端在之后的请求中会比较当前时间与Expires的时间,决定是否需要重新获取资源。

    • If-None-Match: 当客户端发送一个GET请求时,可以附带这个头部,其中的值是之前从服务器获取的ETag值(由服务器生成的资源标识符)。服务器会比较客户端提供的If-None-Match值与当前资源的ETag值,如果相同,则返回状态码304 Not Modified,表示资源没有发生改变。

    • Cookie: 包含了之前由服务器发送的Cookie,格式为Cookie: name=value。服务器可以根据这个头部来识别用户。

    • Referer: 表示发送请求的页面的URL,格式为Referer:https://www.example.com/page.html。通常用于跟踪链接来源。

    • Origin: 表示发起请求的页面的源信息,格式为Origin:https://www.example.com。用于跨源资源共享(CORS)。

    • User-Agent: 标识发送请求的客户端应用程序类型、操作系统、版本等信息,格式为User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3。服务器可以根据这个头部来适应不同的客户端。

    • ETag: ETag是实体标签的缩写,是由服务器分配给资源的唯一标识符。它可以是资源的哈希值、版本号或其他标识。当服务器返回响应时,可以通过ETag响应头部将资源的ETag值传递给客户端。客户端可以将这个ETag值作为If-None-Match请求头部的一部分发送回服务器,以便服务器检查资源是否已更改。如果ETag值匹配,服务器可能会返回状态码304 Not Modified,表示资源未更改。

    • Set-Cookie: Set-Cookie响应头部用于在客户端设置一个Cookie。服务器可以通过这个头部告知客户端在之后的请求中包含特定的Cookie。例如,Set-Cookie: sessionid=123456789会在客户端设置一个名为sessionid的Cookie,以便客户端在后续请求中发送回服务器。

    • Server: Server响应头部指示响应的服务器类型和版本。这个头部可以用于客户端了解正在与之通信的服务器的一些信息。

  • 请求头部的使用场景(缓存):

    • 强缓存(Strong Caching): 强缓存是通过在HTTP响应头部设置参数来实现的,这些参数告诉客户端可以在一段时间内直接使用缓存的资源,而无需向服务器发送请求。

      • Expires: 指定资源的过期时间,是一个绝对时间,客户端会在过期时间之前直接使用缓存。
      • Cache-Control: 使用Cache-Control头部的max-age指令,指定资源可以在客户端缓存的最大时间(单位为秒)。
    • 协商缓存(Conditional Caching): 协商缓存是通过在HTTP请求和响应头部之间进行交互,确定是否需要从服务器获取资源的最新版本。客户端发送条件性请求到服务器,服务器根据条件判断资源是否发生了变化,然后返回适当的响应。

      • ETag/If-None-Match: 客户端在请求头部中发送上一次请求时服务器返回的ETag值,服务器比较这个值与当前资源的ETag值,如果匹配,则返回状态码304 Not Modified
      • Last-Modified/If-Modified-Since: 客户端在请求头部中发送上一次请求时服务器返回的Last-Modified时间,服务器会比较这个时间与资源的最后修改时间,如果没有变化,则返回状态码304 Not Modified,客户端使用缓存。
  1. Cookie(Set-Cookie-response)

当服务器向客户端(浏览器)发送HTTP响应时,可以使用HTTP头部字段“Set-Cookie”来设置Cookie。Cookie是一种存储在客户端浏览器中的小段数据,用于跟踪用户会话、存储用户偏好设置、记录用户行为等。

  • Set-Cookie字段格式: Set-Cookie: name=value; [属性]
  • 多个Cookie的设置: 一个HTTP响应可以包含多个Set-Cookie头部,用于在同一响应中设置多个Cookie。
  • 注意事项: 设置Cookie时需要注意安全性和隐私问题。敏感信息不应直接存储在Cookie中,以防止被恶意用户访问。另外,使用适当的属性设置可以增加Cookie的安全性和控制范围。

发展

  1. HTTP2.0

HTTP/2.0(通常简称为HTTP2),指的是一种用于在Web上传输数据的网络协议,它是HTTP/1.1的后继版本。HTTP/2旨在提高性能,减少延迟,增强安全性,以适应现代Web应用的需求。

  • 背景: 在HTTP/1.1中,浏览器在请求和响应之间必须按照特定的顺序进行通信,这可能导致“队头阻塞”(head-of-line blocking)问题,其中一个请求的延迟会影响其他请求的传输。为了解决这个问题,HTTP/2引入了一些新特性。
  • 多路复用(Multiplexing): HTTP/2引入了多路复用机制,允许在同一连接上同时发送多个请求和响应。这意味着不再需要为每个请求都建立单独的连接,从而减少了连接建立和关闭的开销,提高了性能。
  • 二进制分帧(Binary Framing): HTTP/2将数据分割为二进制帧(frames),每个帧都具有唯一的标识符,这些帧可以并行传输,而无需等待前一个请求完成。这有助于解决队头阻塞问题。
  • 首部压缩(Header Compression): 在HTTP/1.1中,请求和响应的首部信息(headers)需要重复发送,浪费了带宽和时间。HTTP/2使用HPACK算法对首部进行压缩,减少了数据传输量,提高了效率。
  • 服务器推送(Server Push): HTTP/2允许服务器在客户端请求之前主动推送相关资源,以减少客户端的等待时间。例如,服务器可以在客户端请求HTML页面时,主动将该页面引用的样式表和脚本文件推送到客户端,从而提前加载所需资源。
  • 流(Stream): 在HTTP/2中,每个请求-响应交互被称为一个流(stream)。多个流可以在一个连接上并行传输,从而提高了并发性能。
  • 优先级(Priority): HTTP/2允许客户端为每个流设置优先级,以指示服务器哪些请求应该优先处理。这有助于更有效地分配服务器资源。
  • 安全性: HTTP/2对安全性有一定的要求,大多数现代浏览器要求使用HTTPS连接才支持HTTP/2。这有助于保护数据的隐私和完整性。
  1. HTTPS

    HTTPS(Hypertext Transfer Protocol Secure)是一种用于在互联网上安全传输数据的协议。它是基于HTTP协议的扩展,通过加密通信来保护数据的隐私和完整性,防止数据在传输过程中被恶意篡改或窃取。

  • 加密通信: HTTPS使用加密算法来对传输的数据进行加密,使得第三方无法轻易解读或修改传输的内容。这对于保护敏感信息(如个人信息、登录凭据、支付信息等)在互联网上传输非常重要。
  • SSL/TLS协议: HTTPS的安全性是通过使用SSL(Secure Sockets Layer)或其后续版本TLS(Transport Layer Security)来实现的。这些协议提供了加密、身份验证和数据完整性保护等功能。
  • 数字证书: 在建立HTTPS连接时,服务器需要使用数字证书来验证其身份。数字证书是由权威的证书颁发机构(CA,Certificate Authority)签发的,用于证明服务器是合法的。客户端浏览器会验证证书的合法性,以确保连接的目标是真实可信的。
  • 加密过程: 当客户端(通常是浏览器)尝试与服务器建立HTTPS连接时,以下步骤发生在加密过程中:
    • 客户端Hello: 客户端向服务器发送一个加密握手请求,包括所支持的加密算法和其他参数。
    • 服务器Hello: 服务器从客户端的请求中选择一个合适的加密算法,并返回加密握手响应,包括服务器的数字证书。
    • 客户端验证证书: 客户端验证服务器的数字证书,确保它的合法性和真实性。
    • 密钥交换: 使用服务器的公钥,客户端生成一个临时的对称密钥(会话密钥),并通过服务器的公钥进行加密,然后发送给服务器。
    • 握手完成: 服务器使用私钥解密客户端发送的临时密钥,从而获取会话密钥。此后,客户端和服务器使用会话密钥进行加密通信,保护数据的隐私和完整性。
  • HTTP和HTTPS的区别: 主要区别在于通信方式。HTTP是明文传输,数据可以被拦截和窃取,而HTTPS使用加密进行传输,数据更安全。使用HTTPS还可以提升网站的信任度,因为用户可以通过绿色的锁图标或网址前的https://来识别安全连接。
  • 性能影响: 尽管HTTPS提供了更高的安全性,但加密和解密过程会增加服务器和客户端的计算负担,从而可能略微影响性能。为了解决这个问题,一些技术如HTTP/2可以在HTTPS连接中提高性能。
  • 配置和部署: 部署HTTPS需要获取有效的数字证书,并进行服务器配置。证书可以是付费的,也可以通过免费的证书颁发机构(如Let's Encrypt)获取。服务器配置需要将SSL/TLS设置正确配置,以确保安全性和兼容性。

三、常见场景

静态资源

HTTP协议在处理静态资源方面有许多应用场景,这些场景旨在优化性能、加速页面加载以及提供更好的用户体验。

HTTP协议在静态资源应用场景分析:

  • 缓存控制: HTTP协议通过缓存控制头部来定义浏览器如何缓存静态资源。通过设置“Cache-Control”和“Expires”头部,服务器可以指示浏览器在一定时间内重复使用已下载的资源,从而减少对服务器的请求,提高加载速度。这对于不经常变化的静态资源(如图像、样式表)尤为有效。
  • 并行下载: 静态资源可以同时从同一服务器或不同服务器的不同域名上下载。浏览器对每个域名有连接数的限制,因此使用多个域名加载静态资源可以允许更多的并行下载,从而提高页面加载速度。
  • 内容分发网络(CDN): CDN是一种专门用于提供静态资源的分发网络。CDN服务器位于全球各地,能够更接近用户,从而减少数据传输的距离,提高加载速度。通过将静态资源部署到CDN上,网站可以加速资源传输,减轻原始服务器的负担。
  • 资源压缩: HTTP协议支持对静态资源进行压缩,以减小文件大小。压缩后的资源需要更少的带宽传输,加快下载速度。常用的压缩算法有Gzip和Brotli,服务器和浏览器都可以支持。
  • 版本控制: 为了避免浏览器缓存旧版本的静态资源,开发人员可以通过添加版本号、哈希值或日期戳等方式,在每次更新静态资源时改变资源的URL。这会迫使浏览器重新下载最新版本的资源,而不会使用缓存中的旧版本。
  • 减少HTTP请求: 网页性能优化的一个关键点是减少HTTP请求次数。通过合并多个CSS文件或JavaScript文件为一个文件,或者使用CSS雪碧图(CSS Sprites)将多个图像合并为一个图像,可以减少HTTP请求次数,从而加快页面加载速度。
  • 响应头优化: 静态资源的响应头部也可以进行优化。例如,使用适当的缓存策略头部、启用跨域资源共享(CORS)、启用HTTP/2以支持多路复用等技术,可以进一步提升静态资源的加载性能和安全性。

登录

HTTP协议在登录应用场景中起着重要作用,这是因为登录涉及用户身份验证和会话管理,是大多数Web应用程序的核心功能之一。

HTTP协议在登录应用场景分析:

  • 用户身份验证: 登录是通过验证用户提供的凭据来确认用户身份的过程。在HTTP协议中,通常使用POST请求来向服务器发送用户的用户名和密码等凭据。服务器会验证凭据的正确性,然后根据验证结果返回相应的HTTP响应。
  • 安全传输: 由于登录涉及敏感信息(如用户名和密码),在登录过程中使用HTTPS协议是非常重要的。HTTPS使用加密通信来保护数据的隐私和完整性,防止凭据在传输过程中被恶意拦截或窃取。
  • Cookie和会话管理: 一旦用户通过登录验证,服务器会生成一个唯一的会话标识,通常以Cookie的形式存储在用户的浏览器中。该Cookie包含会话标识符,服务器可以使用这个标识符来识别用户,以及在整个会话期间保持用户的状态。这允许用户在多个页面之间保持登录状态,而无需每次都重新输入凭据。
  • 安全性考虑: 在登录应用场景中,安全性是关键问题。应避免将密码以明文形式存储在服务器上,通常使用加密散列算法对密码进行哈希处理,以增加密码的安全性。此外,对登录尝试进行限制(如限制尝试次数)可以防止暴力破解攻击。
  • 单点登录(SSO): HTTP协议可以与单点登录系统集成,允许用户在多个关联的应用程序中使用一组凭据进行登录。这可以提供便捷的用户体验,并简化用户管理。
  • 跨站请求伪造(CSRF)保护: 登录应用场景还需要注意防止跨站请求伪造攻击。这可以通过使用CSRF令牌和验证referer头部等方式来保护。
  • 会话超时和注销: 用户登录后,会话应该有一定的超时时间,以防止未经授权的访问。此外,提供注销功能允许用户主动终止会话,从而保护其隐私和安全。

四、实际应用

浏览器

  1. ajax的XHR

HTTP协议的浏览器中使用的XMLHttpRequest(XHR)是一种用于发起HTTP请求并与服务器进行通信的JavaScript API。XHR允许在不刷新整个页面的情况下,异步地获取数据和更新页面内容,从而提供了更好的用户体验。

  • XMLHttpRequest:
    • 创建XHR对象: 要使用XHR,首先需要创建一个XHR对象。可以通过new XMLHttpRequest()来创建XHR对象。
    • 发起请求: 使用XHR对象可以发起HTTP请求,包括GET、POST等请求类型。通过调用open()方法来指定请求类型、URL和是否异步。
    • 设置请求头: 可以通过setRequestHeader()方法设置请求头部信息,例如设置Content-Type、Authorization等。
    • 监听事件: XHR对象允许注册多个事件监听器,以便在请求不同阶段触发相应的操作。
    • 发送请求: 使用send()方法发送请求。对于GET请求,可以将参数直接附加在URL后面;对于POST请求,需要通过send()方法传递参数。
    • 处理响应: 在XHR的事件监听中,可以通过xhr.responseText获取响应的文本内容,xhr.status获取HTTP状态码,xhr.getAllResponseHeaders()获取所有响应头部等。
    • 处理异步请求: XHR默认以异步方式执行,这意味着它会在后台发起请求,而不会阻塞页面加载。可以通过设置第三个参数为truefalse来控制是否异步。
    • CORS支持: XHR可以用于跨域请求,但受到同源策略的限制。可以通过CORS机制(使用适当的响应头部)来允许跨域请求。
    • 带有进度信息的请求: XHR还可以用于带有进度信息的请求,如上传和下载文件。可以通过监听progress事件来监视进度。
    • 中止请求: 可以使用abort()方法中止正在进行的请求。
  • readyState:
    • 0 - 未初始化 (UNSENT): 这是XMLHttpRequest对象创建后的初始状态。在这个阶段,open()方法还没有被调用,因此请求也没有被初始化。readyState为0时,可以通过open()方法来设置请求的方法(GET、POST等)以及URL。
    • 1 - 正在加载 (OPENED): 在这个状态下,XMLHttpRequestopen()方法已经被调用,请求已经初始化,但是还没有发出。可以通过调用send()方法来实际发出请求。此时,也可以设置请求头部信息。
    • 2 - 已发送 (HEADERS_RECEIVED): 当请求被成功发送到服务器并且服务器已经返回响应头部时,readyState将变为2。在这个状态下,可以访问服务器返回的响应头部信息,比如响应状态码。
    • 3 - 正在接收响应体 (LOADING): 一旦服务器开始发送响应体数据,readyState会变为3。此时,可以通过responseTextresponseXML属性来获取部分响应体数据。这对于处理大文件或流式数据很有用。
    • 4 - 请求完成 (DONE): 当整个请求-响应过程完成时,readyState将达到4。在这个状态下,可以获取完整的响应体数据。此外,也可以检查响应状态码来判断请求是否成功(通常是状态码为200)。
  1. ajax的Fetch

Fetch是一个用于在浏览器中发起HTTP请求的API,它是XMLHttpRequest(XHR)的现代化替代方案。

  • 基本使用: 使用Fetch API,可以通过fetch()函数发起HTTP请求。fetch()函数返回一个Promise对象,可以用于处理异步操作。
  • 发起GET请求: 使用fetch()函数默认发起GET请求。
  • 发起其他请求类型: 可以通过fetch()函数的第二个参数来指定请求的类型(GET、POST、PUT等)以及其他请求配置。
  • 处理响应: 在Promise的then()块中,可以使用response对象来处理响应,包括获取响应的状态码、头部、数据等。
  • 处理跨域请求: 默认情况下,Fetch API受到同源策略的限制,但可以通过服务器设置CORS(跨域资源共享)响应头部来允许跨域请求。
  • 请求头配置: 可以通过headers参数来配置请求头部。例如,指定Content-Type,设置Authorization等。
  • 处理JSON数据: 通过response.json()方法可以解析JSON格式的响应数据。
  • 带有进度信息的请求: Fetch API允许在上传或下载文件等情况下,使用response.body以及监听progress事件来获取请求和响应的进度信息。
  • 处理错误: 在Promise的catch()块中,可以处理请求发生的错误,例如网络错误、服务器错误等。

node

  1. 标准库:HTTP/HTTPS
  • http模块: http模块是Node.js内置的用于处理HTTP协议的模块。可以使用它来创建HTTP服务器、发起HTTP请求以及处理HTTP响应。

    • 创建HTTP服务器: 使用http.createServer()方法可以创建一个HTTP服务器实例。你需要传递一个回调函数,该函数会在每次有HTTP请求到达服务器时被调用。在回调函数中,可以处理请求、设置响应头、发送响应数据等。
    • 处理请求和响应: 在HTTP请求回调函数中,可以访问请求对象(req)和响应对象(res)。请求对象包含了来自客户端的请求信息,如URL、HTTP方法和头部信息。响应对象用于设置响应状态码、头部和发送响应体数据。
    • HTTP请求: 使用http.request()方法可以发起HTTP请求到其他服务器。你可以指定请求的方法、URL、头部信息,并在回调函数中处理响应。
  • https模块: https模块是Node.js内置的用于处理HTTPS协议的模块,它扩展了http模块的功能,使其支持安全的加密通信。

    • 创建HTTPS服务器: 类似于http.createServer()https.createServer()方法用于创建一个HTTPS服务器。需要提供SSL证书和密钥,用于加密和验证通信。
    • 安全通信: 与HTTP不同,HTTPS通过TLS/SSL协议加密通信,确保数据在传输过程中是安全的。需要提供证书和密钥,以确保服务器和客户端之间的加密通信。
  1. 常用的请求库:axios

axios是一个在Node.js和浏览器中都可使用的流行的HTTP客户端库,用于发起HTTP请求并处理响应。它提供了简单易用的API,使得在Node.js环境中进行HTTP通信变得更加方便。

  • 安装和导入: 需要使用Node.js的包管理器(如npmyarn)安装axios库。

    • 在终端中运行以下命令:npm install axios
    • 在Node.js脚本中,导入axios模块:const axios = require('axios');
  • 发起HTTP请求: axios提供了多种方法用于发起不同类型的HTTP请求,如GET、POST、PUT等。你可以使用这些方法指定请求URL、传递参数、设置请求头等。

    • 发起GET请求
    axios.get('https://api.example.com/data')
        .then(response => {
            console.log(response.data); // 响应数据
        })
        .catch(error => {
            console.error('请求错误:', error);
        });
    
    • 发起POST请求
    axios.post('https://api.example.com/post', { data: 'value' })
        .then(response => {
            console.log(response.data);
        })
        .catch(error => {
            console.error('请求错误:', error);
        });
    
  • 处理响应: 一旦请求被发送并且响应被接收,可以使用.then()方法来处理成功的响应,使用.catch()方法来处理错误的情况。在.then()中,你可以通过response对象访问响应数据、状态码、头部等信息。

  • 拦截器: axios支持请求和响应的拦截器,允许在请求发送前和响应返回后执行额外的逻辑。这对于添加全局的请求头、进行错误处理等非常有用。

  • 取消请求: axios允许你创建一个可取消的请求。可以使用CancelToken来创建一个取消令牌,然后在需要取消请求时调用cancel()方法。

  • 设置全局配置: 可以设置全局的默认配置,如基础URL、超时时间等,以便在多个请求中共享相同的配置。

五、了解更多

WebSocket

WebSocket是一种基于TCP协议的全双工通信协议,它允许在一个单独的持久连接上进行双向通信。与HTTP不同,WebSocket不需要在每次通信时都重新建立连接,这使得实时性和效率得到显著提升。

  • 握手过程: WebSocket通信的起点是一个特殊的HTTP请求,称为握手(Handshake)。握手请求包含了一些特殊的头部信息,其中包括UpgradeConnectionSec-WebSocket-Key等。如果服务器支持WebSocket,它将返回一个带有UpgradeConnection头部的响应,表示成功建立WebSocket连接。之后,连接将转换为WebSocket协议,变为持久的全双工通信通道。
  • 持久连接: 一旦WebSocket连接建立,它将保持打开状态,允许服务器和客户端随时进行双向通信,而不需要频繁地重新建立连接。这种持久连接使得实时性通信、推送消息和交互式应用变得更加高效。
  • 数据帧(Frame): WebSocket通信是通过数据帧来传输数据的。数据帧是WebSocket通信的基本单位,可以是文本数据、二进制数据等。每个数据帧都包含一些元数据,如数据类型、是否分片等。数据帧通过WebSocket连接按顺序传输,并且不会受到HTTP请求和响应的限制。
  • 双向通信: 与HTTP请求-响应模型不同,WebSocket允许服务器和客户端在任何时候都可以发送数据,而不需要等待对方的请求。这使得服务器可以主动向客户端推送消息,实现实时性应用,如聊天应用、实时游戏等。
  • 关闭连接: 要关闭WebSocket连接,可以通过发送特殊的关闭帧来实现。这种关闭帧将通知对方连接即将关闭,并允许双方完成任何必要的清理工作。一旦连接关闭,双方将不能再发送数据。
  • 安全性: 与HTTP一样,WebSocket通信也可以通过TLS/SSL协议进行加密,以确保数据的安全性。通过在URL中使用wss://而不是ws://来指定安全的WebSocket连接。

QUIC:Quick UDP Internet Connection

QUIC是基于UDP(用户数据报协议)的,并且旨在提供更快的连接建立和更低的通信延迟。

  • UDP为基础: 传统的网络通信协议,例如TCP(传输控制协议),在建立连接和数据传输方面有一定的开销。而QUIC基于UDP协议,这意味着它可以更快地建立连接和传输数据,因为它避免了TCP的一些延迟。
  • 多路复用: QUIC 支持多路复用,这意味着多个数据流可以通过单个 QUIC 连接传输。这有助于减少连接的数量,从而降低了连接建立的成本和时间。
  • 连接迁移: QUIC 允许在不中断连接的情况下,将数据从一个网络接口迁移到另一个网络接口。这对于移动设备在切换网络时保持连接是非常有用的。
  • 0-RTT 连接建立: QUIC 支持0-RTT(零往返时间)连接建立。这意味着在已建立的连接上,客户端和服务器之间可以在不等待往返时间的情况下立即交换数据,从而加快了首次连接建立时的延迟。
  • 安全性: QUIC 内置了加密,通过TLS(传输层安全)协议保护数据的传输和隐私。这有助于防止数据被窃听或篡改。
  • 拥塞控制: QUIC 使用自己的拥塞控制算法,可以更好地适应网络状况,从而减少网络拥塞带来的性能下降。
  • 快速握手: QUIC 的连接握手过程相对较快,这是因为它减少了往返时间,同时允许服务器在握手过程中立即发送数据。
  • 适应性: QUIC 被设计成可以轻松地扩展和适应新的网络技术,例如 IPv6 和新的加密算法。
  • 中断恢复: 如果连接中断,QUIC 可以更快地恢复连接,而不需要重新建立整个连接。
  • 部署挑战: 尽管QUIC带来了许多优势,但在广泛部署过程中也会面临一些挑战。某些网络环境可能会限制UDP流量,而且因为QUIC是相对较新的协议,需要确保与旧有的网络设备和中间设备兼容。

本篇笔记为个人总结,学习交流使用,欢迎各位大佬评价指正,非常感谢!