【HTTP完全注解】我绝对要让你看懂HTTP报文🫵

完整手册可关注该仓库,如有帮助,麻烦给个✨

该站点也会同步更新,已满足PWA,您可安装到桌面随时/离线访问

HTTP报文格式

HTTP报文是简单的、面向行的字符序列,它承载了HTTP客户端发送请求和服务器返回响应的所有信息,其格式至HTTP/1.0首次定义以来一直沿用至今 。在HTTP/2之前,报文在传输过程中都是使用纯文本,而不是二进制,而HTTP又是使用明文传输,因此非常容易就能窃取HTTP报文中的内容。在 HTTP/2 中这些问题得到了改善,报文被嵌入到了一个新的二进制结构------帧中,虽然报文被嵌入到了新的结构中,但每条报文的语义依旧不变,因此用之前的报文格式来理解 HTTP/2 报文仍旧有效

HTTP报文有请求、响应两种类型,它们都由起始行、消息头与消息体构成

  • 报文的第一行被称为起始行,起始行是必须存在的,它包含了请求/响应的基本信息
  • 报文的第二行至空白行被称为消息头,消息头有些是可选的,有些则是必须的,它包含了一系列的key:value键值对(key不区分大小写),用来描述请求或响应的附加信息
  • 报文的空白行后一行至最后一行被称为消息体,消息体是可选的,它用来携带请求或响应需要上传/响应的具体内容

请求报文中起始行、消息头与消息体又被称为请求行、请求头以及请求体。在响应报文中起始行、消息头与消息体又被称为响应行、响应头以及响应体目前HTTP的起始行和消息头仍是使用ASCII编码,而消息体则是根据消息头中的内容协商来决定具体编码方式

起始行

报文中的第一行被称为起始行,它是必须存在的,包含了请求/响应的基本信息起始行在请求报文中被称为请求行在响应报文中又被称为响应行。请求行与响应行有很大的差别:

  • 请求行由Method(请求方法)、Path(请求资源路径,通常是一个 URL)以及HTTP/Version(HTTP版本)组成,它们使用空格分隔,以此区别
  • 响应行由HTTP/Version(HTTP版本)、Code(状态码)以及Message(返回消息)组成,它们也使用空格分隔,以此区别

Method

HTTP 定义了9个请求方法,以表明要对给定资源执行的操作,每个HTTP请求报文都必须使用一个请求方法来告诉服务器应该执行什么样的操作。

请求方法 操作
GET GET 方法用于请求获取指定资源的信息,GET 请求应该只被用于获取数据。
HEAD HEAD请求与GET请求类似,但是服务器在响应中只返回响应头部信息,而不返回实际的资源内容。HEAD请求常用于获取资源的元数据,如资源的大小、修改时间等,而不需要获取实际的资源内容,以减少不必要的数据传输。
POST POST 方法用于向服务器提交数据,POST请求通常会对服务器状态进行修改。
PUT PUT 方法用于向服务器上传或更新指定资源的内容,PUT请求通常用于更新已存在的资源,如果资源不存在,则可以创建一个新资源。
DELETE DELETE 方法用于请求删除服务器上指定的资源。
PATCH PATCH 方法用于对资源进行部分修改。
OPTIONS OPTIONS方法用于获取服务器支持的请求方法和资源的通信选项,当发送一个OPTIONS请求时,服务器会返回一个包含允许的请求方法、支持的头部字段等信息的响应。
TRACE TRACE请求用于追踪请求-响应的传输路径。当发送一个TRACE请求时,服务器会原样返回请求中的数据,这样客户端就可以查看中间代理服务器对请求的修改情况,用于诊断和调试网络传输问题。
CONNECT CONNECT请求用于在客户端和服务器之间建立隧道连接,以此进行加密通信或代理服务器的连接。

请求方法可以被分为安全/不安全的方法幂等/不幂等的方法 以及可被缓存/不可被缓存的方法

幂等的请求方法

幂等的请求方法指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。 在正确实现的条件下, GETHEADPUTDELETEOPTIONS以及TRACE等方法都是幂等的方法。其他方法不幂等的原因如下:

  • CONNECT方法因为它涉及建立网络连接,而连接的状态可能会因多次执行而不同,所以它并不是幂等的方法。
  • POST用于向资源提交数据,多次执行相同的POST请求通常会导致资源状态的改变,因为每次请求可能会创建新的资源或者对现有资源进行修改。但是,具体是否幂等取决于服务器的实现,有些服务器可以对相同的POST请求进行幂等处理。
  • PATCH方法用于对资源进行局部更新,多次执行相同的PATCH请求通常会产生相同的结果,因为它们只是更新资源的一部分。但是,具体是否幂等取决于服务器的实现,因为某些情况下,多次执行相同的PATCH请求可能会导致不同的结果,例如,如果同时有其他并发请求影响了资源的状态。
是否幂等 请求方法
幂等 GET、HEAD、OPTIONS、PUT、DELETE、TRACE
不幂等 PATCH、CONNECT、POST

安全的请求方法

安全的请求方法指这些方法不会修改服务器的数据以及改变服务器的状态 ,也就是说,这是一个对服务器只读操作的方法。不难发现在正确实现的条件下,GETHEADOPTIONSTRACE都是对服务器只读操作的方法,因此它们是安全的方法所有安全的方法都是幂等的,但并非所有幂等方法都是安全的 ,例如,PUTDELETE 都是幂等的,但不是安全的。

是否安全 请求方法
安全 GET、HEAD、OPTIONS、TRACE
不安全 POST、PATCH、PUT、DELETE、CONNECT

可被缓存的请求方法

HTTP协议定义了一些请求方法,其中一些方法通常可以被缓存。 可被缓存的请求方法是那些在满足特定条件下,可以被缓存代理服务器(如HTTP缓存)缓存的方法。以下是常见的能否被缓存的HTTP请求方法:

  • GETHEADOPTIONS方法: GETHEADOPTIONS方法通常被认为是可缓存的,因为它们是幂等且安全的,而且不会改变服务器状态。这意味着代理服务器可以缓存它们的响应,以提高性能并减轻服务器负载。
  • POSTPATCH方法:POSTPATCH方法的响应通常不会被缓存 ,因为它们通常用于向服务器提交数据,可能会改变服务器状态。然而,如果响应中指定了有效期(例如,通过Cache-Control头部)并设置了Content-Location头部,那么它们的响应可以被缓存。这种情况下,缓存代理服务器可以将响应缓存,并在之后的请求中使用。但这种情况下的缓存行为在实际应用中相对较少见,并且有些浏览器并不支持(例如Firefox 就不支持它Firefox bug 109553),因此通常不鼓励缓存POST请求的响应。
  • PUTDELETE方法: PUTDELETE 方法的响应通常不会被缓存 ,即使设置了有效期(通过Cache-Control头部)和Content-Location标头。这是因为这两个请求方法通常用于对资源进行修改或删除,可能会改变服务器的状态,因此响应不适合被缓存。
  • CONNECT 方法:CONNECT 方法的响应通常不会被缓存 ,即使设置了有效期(通过Cache-Control头部)和Content-Location标头。CONNECT 方法用于建立网络连接,通常用于代理服务器。由于 CONNECT 方法的目的是在客户端和目标服务器之间建立连接,而不是获取资源,所以 CONNECT 方法的响应通常不会被缓存。代理服务器通常不会缓存 CONNECT 方法的响应,因为它们不包含可被缓存的资源数据。
  • TRACE 方法:TRACE 方法的响应通常不会被缓存 ,即使设置了有效期(通过Cache-Control头部)和Content-Location标头。TRACE 方法用于在目标服务器上执行一个诊断测试,它返回由服务器收到的请求的副本。由于 TRACE 方法的主要目的是用于诊断和调试,而不是对服务器上的资源进行修改,因此 TRACE 方法的响应通常不会被缓存。代理服务器通常不会缓存 TRACE方法的响应,因为这些响应只包含请求的副本,不包含可被缓存的资源数据。
能否缓存 请求方法
可被缓存 GET、HEAD、OPTIONS
可被缓存,但不鼓励且支持少 POST、PATCH
不可被缓存 PUT、DELETE、CONNECT、TRACE

Path

Path请求资源路径用来表示要请求的资源的网络位置,Path有多种形式:它可以是一个相对URL、也可以是一个绝对URL、也可以仅由一个星号(*)组成。使用什么形式通常以请求方法、请求的环境为以及请求的格式来决定。

Path的形式:

  • 相对URL: 这是最常见的形式,除了CONNECT方法都可以使用。

    bash 复制代码
    / 
    /background.png 
    /test.html?query=alibaba
    /anypage.html
  • 绝对URL: 主要在使用 GET 方法连接到代理时使用。

    bash 复制代码
    https://wangjunliang.com/HTTP-Explanation/index.html
    https://wangjunliang.com/HTML-Guide/index.html
  • 包含端口的绝对URL: 在使用 CONNECT 建立 HTTP 隧道时才使用。

    arduino 复制代码
    https://wangjunliang.com:80
  • 一个星号: 配合 OPTIONS 方法使用,代表整个服务器。

    markdown 复制代码
    *

HTTP/Version

HTTP/Version表明了客户端请求使用的HTTP协议版本,并期望服务器相同的协议版本响应。目前有HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2.0以及HTTP/3.0五种取值,随着HTTP不断发展后续也会有更多的版本。

Code与Message

Code状态码是服务器返回的响应报文响应行中一个三位数字代码,用于表示服务器处理请求的结果状态。它们提供了关于请求是否成功、出现错误的类型以及如何处理请求的信息。

HTTP响应状态码由三个数字组成,分别表示响应的类别:

  • 1xx:信息性状态码,表示服务器接收到请求并继续处理。
  • 2xx:成功状态码,表示服务器成功处理了请求。
  • 3xx:重定向状态码,表示需要进一步操作以完成请求。
  • 4xx:客户端错误状态码,表示客户端发送的请求有错误。
  • 5xx:服务器错误状态码,表示服务器在处理请求时发生了错误。

Message返回消息是服务器返回的响应报文响应行中一个可选的文本描述,返回消息提供了对状态码的进一步解释,使客户端能够更好地理解服务器处理请求的结果。通常称为"Reason-Phrase",它紧跟在状态码后面,以便更清楚地说明状态码的含义。

信息性状态码:1xx

状态码 返回消息 作用
100 Continue 这个临时响应表明,迄今为止的所有内容都是可行的,客户端应该继续请求,如果已经完成,则忽略它。
101 Switching Protocols 该代码是响应客户端的 Upgrade请求头发送的,指明服务器即将切换的协议。
102 Processing 该代码是一个临时的状态码,用于指示服务器已经接收到请求并且正在处理,但尚未完成处理。这个状态码通常用于长时间运行的请求或者需要进行大量计算的请求。
103 Early Hints 此状态代码主要用于与Link消息头一起使用,以允许用户代理在服务器准备响应阶段时开始预加载preloading资源。当服务器收到客户端的请求后,如果服务器能够提前获取到一些与请求相关的资源或者其他信息,它可以使用103状态码来发送这些信息的响应头部给客户端。这样,客户端在接收到完整的响应之前,就可以开始预加载或处理这些额外的信息,从而提高页面加载速度和用户体验。该状态码仍处于实验阶段。

成功状态码:2xx

状态码 返回消息 作用
200 OK 请求成功并已正确处理返回
201 Create 请求成功,并因此创建了一个新的资源。这通常是在 POST 请求,或是某些 PUT 请求之后返回的响应。
202 Accepted 表示请求已被接受,但处理尚未完成。通常情况下,服务器会在响应中包含一个描述性的消息或链接,以便客户端可以进一步跟踪请求的处理进度。这通常用在异步操作或批量操作的场景中
203 Non-Authoritative Information 表示服务器已成功处理请求,但返回的信息可能来自于另一个源。通常用于代理服务器的场景,表示代理服务器已经接收到请求并成功处理,但返回的响应内容是从其他服务器获取的,这种情况下,响应中会包含一个描述性的消息或链接,指示客户端可以从其他源获取更详细的信息。
204 No Content 表示请求成功处理,但没有返回内容。
205 Reset Content 表示请求成功处理,要求客户端重置(Reset)当前页面。
206 Partial Content 表示服务器成功处理了部分GET请求,只返回了请求范围内的部分内容。通常用于对资源进行分段下载以及断点续传的场景

重定向状态码:3xx

状态码 返回消息 作用
300 Multiple Choice 请求拥有多个可能的响应,用户代理或者用户应当从中选择一个。服务器在响应中会包含一个Location头部字段,其中列出了多个可供选择的资源的URL 。 客户端可以根据自己的需求选择其中一个URL进行进一步的请求。需要注意的是,300状态码并不会自动重定向到其中的某个URL,而是提供了多个选择供客户端选择。
301 Moved Permanently 请求资源的 URL 已永久更改,在响应中给出了新的 URL。当服务器返回301状态码时,客户端会被告知该资源已经永久移动,并且会在响应的Location头部字段中提供新的URL。客户端收到301响应后, 会使用相同的请求方法(一些浏览器可能将POST请求自动转换为GET请求)自动重定向到新的URL,以便获取所请求的资源。
302 Found 请求资源的 URL 临时移动到了一个不同的URL,在响应中给出了新的 URL。当服务器返回302状态码时 ,客户端会被告知该资源已经临时移动,并且会在响应的Location头部字段中提供新的URL。与301状态码不同,302状态码表示所请求的资源只是临时移动,而不是永久性的移动。客户端收到302响应后,会使用相同的请求方式(一些浏览器可能会将将POST请求自动转换为GET请求)自动重定向到新的URL
303 See Other 表示请求的资源可以在另一个URL上找到,并且客户端应该使用GET方法去获取该资源。当服务器返回303状态码时,客户端会被告知所请求的资源可以在另一个URL上找到,并且在响应的Location头部字段中提供新的URL。与302状态码类似,客户端会自动重定向到新的URL,但是在重定向时会使用GET方法。
304 Not Modified 用于缓存的目的,表示所请求的资源在客户端缓存中仍然有效,并且可以直接使用缓存的副本。当客户端发送一个GET请求时,服务器会检查该请求中的If-Modified-Since或If-None-Match头部字段,这些字段包含了之前获取该资源时服务器返回的Last-Modified或ETag值。如果服务器判断该资源自上次请求以来没有发生变化,就会返回304状态码,告知客户端可以使用缓存的副本。
307 Temporary Redirect 请求的资源的 URL 临时移动到了另一个URL,在响应中给出了新的URL。与302状态码类似,当服务器返回307状态码时,客户端会被告知所请求的资源临时移动到了另一个URL上,并且在响应的Location头部字段中提供新的URL。客户端会自动重定向到新的URL,但在重定向时会保持原始的请求方法(解决了302一些浏览器会将POST转换为GET的问题)。
308 Permanent Redirect 请求资源的 URL 已永久更改,在响应中给出了新的 URL。当服务器返回308状态码时,客户端会被告知该资源已经永久移动,并且会在响应的Location头部字段中提供新的URL。客户端会自动重定向到新的URL,但在重定向时会保持原始的请求方法(解决了301一些浏览器会将POST转换为GET的问题)。

客户端错误状态码:4xx

状态码 返回消息 作用
400 Bad Request 由于被认为是客户端错误(例如,错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或不会处理请求。
401 Unauthorized 表示请求需要用户进行身份验证,但是发送请求的客户端未提供有效的凭据,或者根本没有提供任何凭据。
402 Payment Required 此响应代码保留供将来使用。创建此代码的最初目的是将其用于数字支付系统,但是此状态代码很少使用,并且不存在标准约定。
403 Forbidden 客户端没有访问内容的权限;也就是说,它是未经授权的,因此服务器拒绝提供请求的资源。与401 Unauthorized不同,服务器知道客户端的身份。
404 Not Found 服务器找不到请求的资源。
405 Method Not Allowed 服务器知道请求方法,但目标资源不支持该方法。
406 Not Acceptable 表示服务器无法根据客户端发送的请求中的Accept头部字段,提供与客户端可接受的响应内容格式相匹配的响应。
407 Proxy Authentication Required 类似于 401 Unauthorized 但是认证需要由代理完成。
408 Request Timeout 此响应由一些服务器在空闲连接上发送,即使客户端之前没有任何请求。这意味着服务器想关闭这个未使用的连接。由于一些浏览器,如 Chrome、Firefox 27+ 或 IE9,使用 HTTP 预连接机制来加速冲浪,所以这种响应被使用得更多。还要注意的是,有些服务器只是关闭了连接而没有发送此消息。
409 Conflict 表示服务器在处理请求时发现了冲突,无法完成请求。在进行资源更新或修改操作时,如果服务器检测到当前资源状态与请求中的条件不符合,就会返回409状态码。
410 Gone 当请求的内容已从服务器中永久删除且没有转发地址时,将发送此响应,客户端需要删除缓存和指向资源的链接
411 Length Required 表示服务器要求在请求中包含有效的Content-Length头字段,用于指定请求正文的长度。
412 Precondition Failed 表示服务器在处理请求时,发现请求中包含的某些前提条件不满足。当使用条件请求头字段如If-Match或If-Unmodified-Since时,服务器会比较请求头中的条件与资源的当前状态。如果条件不匹配或资源在指定时间之后被修改过,则服务器会返回412状态码。当使用条件请求头字段如If-None-Match或If-Modified-Since时,服务器会比较请求头中的条件与资源的当前状态。如果条件匹配或资源在指定时间之后未被修改过,则服务器会返回412状态码。
413 Payload Too Large 表示请求实体(负载)的大小超过了服务器设定的限制。如果请求负载超过了服务器定义的限制,服务器可能会选择关闭与客户端的连接,以避免处理过大的请求负载。服务器也可能返回重试信息,在响应中包含一个Retry-After标头字段,指示客户端在多长时间后可以重试请求。这允许客户端知道何时重新发送较小的请求
414 URI Too Long 客户端请求的 URI 比服务器愿意接收的长度长。
415 Unsupported Media Type 服务器不支持请求数据的媒体格式,因此服务器拒绝请求。
416 Range Not Satisfiable 表示服务器无法满足请求中 Range 标头字段指定的范围。该范围可能无效或超出了目标资源数据的大小。
417 Expectation Failed 表示服务器无法满足请求中的Expect请求头字段指定的预期条件
418 I'm a teapot 服务端拒绝用茶壶煮咖啡。笑话,典故来源茶壶冲泡咖啡
421 Misdirected Request 表示服务器无法处理请求,因为请求被发送到了错误的资源。
425 Too Early 表示服务器拒绝处理请求,因为请求的时间过早。该状态码通常与WebRTC(Web实时通信)相关,用于指示客户端在协议协商之前发送了请求。WebRTC是一种用于实时音视频通信的开放标准,它涉及到协议协商和建立连接的过程。在进行协议协商之前,客户端不应该发送任何请求。该状态码处于实验阶段。
426 Upgrade Required 服务器拒绝使用当前协议执行请求,但在客户端升级到其他协议后可能愿意这样做。 服务端发送带有Upgrade 字段的 426 响应 来表明它所需的协议。
428 Precondition Required 表示服务器要求客户端在发送请求之前满足某些先决条件。在收到428状态码时,客户端应该检查响应的头部信息,特别是Precondition-Required头部字段。该字段通常会指定客户端需要满足的先决条件,例如提供正确的If-MatchIf-None-Match头部字段,或者提供适当的验证令牌。
429 Too Many Requests 用户在给定的时间内发送了太多请求("限制请求速率")
431 Request Header Fields Too Large 服务器不愿意处理请求,因为其头字段太大。在减小请求头字段的大小后,可以重新提交请求。
451 Unavailable For Legal Reasons 请求了无法合法提供的资源,例如政府审查的网页。

服务器错误状态码:5xx

状态码 返回消息 作用
500 Internal Server Error 表示服务器内部错误。当服务器在处理请求时遇到了意外错误或异常情况,无法完成请求时,会返回500状态码给客户端。
501 Not Implemented 表示服务器不支持客户端所请求的功能或方法。当客户端发送的请求方法是服务器不支持的,或者服务器无法满足请求所需的功能时,会返回501状态码。
502 Bad Gateway 表示作为代理服务器的网关从上游服务器(通常是应用服务器或另一个代理服务器)接收到无效的响应。这可能是由于上游服务器出现故障、网络连接问题或配置错误等原因导致的。简单来说,502错误意味着代理服务器无法正确地转发请求并获得有效的响应。
503 Service Unavailable 表示服务器当前无法处理请求,通常是由于服务器过载或维护导致的。这是一个临时错误,表示服务器暂时无法提供请求的服务。这个响应应该用于临时条件,如果可能的话,响应标头 Retry-After 字段应该包含恢复服务之前的估计时间。网站管理员还必须注意与此响应一起发送的与缓存相关的标头,因为这些临时条件响应通常不应被缓存。
504 Gateway Timeout 表示代理服务器在尝试转发请求时,未能及时从上游服务器接收到响应。这通常是由于上游服务器处理时间过长、连接超时或网络问题导致的。简单来说,504错误意味着代理服务器等待上游服务器响应的时间超过了预设的超时时间。
505 HTTP Version Not Supported 表示服务器不支持请求中使用的 HTTP 版本。
506 Variant Also Negotiates 表示服务器有多个可供选择的表示形式(变体)可用于响应客户端请求时,服务器可以使用内容协商机制来确定最适合客户端的表示形式。然而,如果服务器无法确定最佳的变体,或者服务器拒绝进行协商,就会返回506状态码。
510 Not Extended 表示服务器需要对请求进行进一步扩展才能完成请求。当服务器收到一个请求,但需要额外的扩展来满足请求时,可以返回510状态码。这通常发生在服务器要求客户端提供更多信息或使用特定的扩展头部字段时。510状态码的出现是为了以后的HTTP协议扩展预留的,以便在需要时可以定义新的扩展状态码。在实际应用中,510状态码的使用相对较少,因为大多数常见的HTTP请求可以通过现有的状态码来处理。
511 Network Authentication Required 表示客户端需要进行身份验证才能获得网络访问权限。

消息头

报文的第二行至空白行被称为消息头,它包含了一系列的key:value键值对(key不区分大小写),用来进一步描述请求或消息体,有些消息头是可选的,有些则是必须的消息头在请求报文中被称为请求头,在响应报文中又被称为响应头,请求头与响应头有些可以共用,有些则只能专用,为此它们有以下分类:

  • 请求与响应都可使用的key被称为通用标头
  • 请求报文专用的key称为请求标头
  • 响应报文专用的key称为响应标头
  • 用于标识消息体相关内容的key被称为实体标头

消息体

报文的空白行后一行至最后一行被称为消息体,它用来携带请求或响应需要上传/响应的具体内容,消息体是可选的。 不是所有的请求都消息体:例如获取资源的请求,像 GETHEADDELETEOPTIONS,通常它们不需要主体,同样的也不是所有的响应都有消息体。消息体在请求报文中被称为请求体,在响应报文中又被称为响应体 。请求体与响应体都可以分为两类:

  • 单一资源(Single-resource)主体,由一个单文件组成。该类型的主体由两个标头定义:Content-Type 和 Content-Length。
  • 多资源(Multiple-resource)主体,由多部分主体组成,每一部分包含不同的信息位。通常是和HTML 表单连系在一起。

总结

请求报文 响应报文 差别
起始行 名称:请求行 由method(方法)、path(请求资源地址)以及http/version(http版本)组成 名称:响应行 由http/version(http版本)、code(状态码)以及message(消息)组成 完全不同
消息头 请求头 由一系列的key:value键值对组成 响应头 由一系列的key:value键值对组成 请求与响应都可使用的被称为通用标头 请求报文专用称为请求标头 响应报文专用称为响应标头 消息体专用被称为实体标头
消息体 请求体 响应体 需要上传的内容/需要响应的内容,它们都可分为单一或多资源主体

🎈本节参考

转载需获得作者同意,并表明来源!

相关推荐
程序员小寒23 分钟前
JavaScript设计模式(八):命令模式实现与应用
前端·javascript·设计模式·ecmascript·命令模式
wgod32 分钟前
new AbortController()
前端
UXbot38 分钟前
UXbot 是什么?一句指令生成完整应用的 AI 工具
前端·ai·交互·个人开发·ai编程·原型模式·ux
棒棒的唐1 小时前
WSL2用npm安装的openclaw,无法正常使用openclaw gateway start启动服务的问题
前端·npm·gateway
哔哩哔哩技术1 小时前
使用Compose Navigation3进行屏幕适配
前端
zmj3203242 小时前
MQTT(消息队列遥测传输)
网络·网络协议
咬人喵喵2 小时前
E2.COOL 平台深度解析:从特效分类到实战操作指南
前端·编辑器·svg
RisunJan3 小时前
Linux命令-named-checkzone
linux·前端
小陈工3 小时前
Python Web开发入门(十):数据库迁移与版本管理——让数据库变更可控可回滚
前端·数据库·人工智能·python·sql·云原生·架构
吹晚风吧3 小时前
解决vite打包,base配置前缀,nginx的dist包找不到资源
服务器·前端·nginx