当服务端返回 HTTP 响应时,会带有一个状态码,用于表示特定的请求结果。比如 HTTP/1.1 200 OK,里面的 HTTP/1.1 表示协议版本,200 则是状态码,OK 则是对状态码的描述。
由协议版本、状态码、描述信息组成的行被称为起始行,服务端返回的响应报文中的第一行便是它,然后是响应头和响应体。
而本篇文章,我们来详细聊一聊状态码,看看它都有哪些,以及含义是什么?
首先状态码由三位数字组成,按照第一个数字的不同,可分为五个类别,每个类别的含义如下。
下面我们来分别介绍这五类状态码都有哪些,以及状态码对应的描述是什么。
1xx 系列的 HTTP 状态码属于信息响应类别,这类状态码用于指示客户端请求的初始部分已被接收,并且客户端应继续其请求过程。
那么该系列的状态码都有哪些呢?
如果客户端发送的请求体很大,比如上传大文件,那么在发送整个请求体之前,可以先发送请求的头部(包含一个 Expect: 100-continue 字段)。相当于告诉服务端,大的要来了,如果同意发送请求体,那么就返回一个 100 Contiune 响应。
而服务端在接收到带有 Expect: 100-continue 的请求头部时,可以先进行一些预检查,比如验证请求头部的有效性、检查是否有足够的资源处理请求、或者检查客户端是否有权限。如果这些初步检查通过,服务端则返回 100 Continue 响应,指示客户端继续发送请求体。
因此 100 Contiune 主要用于提高大型请求的处理效率,尤其是在带宽受限或服务端处理能力有限的情况下。然而并非所有的 HTTP 客户端和服务端都支持这个机制,在不支持的情况下,客户端将直接发送整个请求体,不会等待 100 Continue 响应。
1xx 系列的状态码从 HTTP/1.1 才开始支持,HTTP/1.0 不支持。
这个应该都很熟悉,它一般用于协议升级,比如将 HTTP 协议升级成 WebSocket。
首先不管使用什么协议,都有一个握手的过程,它是建立网络连接时双方进行的一系列交互,旨在确保双方能够成功地通信。不同的协议有不同的握手机制,但它们通常都包括以下基本步骤:
但有一些协议在实现握手时,搭了 HTTP 协议的便车,比如 WebSocket,它的握手过程其实就是一个 HTTP GET 请求。利用 HTTP 本身的协议升级特性,伪装成 HTTP,这样就能绕过浏览器沙箱、网络防火墙等限制。
因此建立 WebSocket 连接时会发送一个 GET 请求,并带上两个专用的头字段,表示这不是普通的 HTTP GET,而是要进行协议升级。
另外,为了防止普通的 HTTP 消息被意外识别成 WebSocket,握手消息还额外增加了两个用于认证的头字段。
服务端收到 HTTP 请求报文,看到上面的四个字段,就知道这不是一个普通的 GET 请求了,而是 WebSocket 的升级请求,表示客户端想要建立 WebSocket 连接。
如果服务端同意建立 WebSocket 连接,那么会给客户端返回 101 Switching Protocols 响应报文,客户端收到之后,就知道服务端同意了。
该状态码用于 WebDAV 协议,WebDAV 请求可能包含很多涉及文件操作的子请求,需要很长一段时间才能完成。因此服务端可以直接返回 102 Processing,表示请求已被接收并正在处理中,但目前无响应可用。这样可以防止客户端因长时间得不到响应,而假设请求丢失。
关于 1xx 系列的状态码就是以上几种,它们被称为信息性状态码,用于表示请求的中间状态,因此在日常的 Web 浏览中并不常见。但 1xx 状态码在复杂的 HTTP 通信中扮演重要角色,特别是在优化性能和处理大型请求、复杂请求时。
2xx 系列的状态码应该最受开发者喜欢了,因为它表示请求被成功处理。
这是最常见的成功状态码,它表示请求已成功处理,并且响应体中包含了请求的结果。
同样表示请求已被成功处理,并且还创建了一个新资源。
当客户端通过 POST 请求向服务端发送数据以创建新资源(如新的数据库记录、文件等)时,如果请求成功并且新资源被创建,服务端会响应 201 Created。
与 200 OK 相比,201 Created 响应不仅表明请求成功,而且还指出了一个新的资源已经产生。响应中一般会包含一个 Location 字段,指明新创建资源的 URI,这对客户端来说非常有用,因为它可以直接使用这个 URI 来访问新创建的资源。
当然啦,由于习惯,很多时候我们还是会返回 200,并将新创建资源的信息放在响应体中。具体使用哪种看个人习惯,总之 200 和 201 没太大区别,只是 201 意味着要明确地告诉客户端,新的资源已经创建了。
表示服务端已收到请求,但尚未处理完成,这种设计可以覆盖很多的场景,例如异步、需要长时间处理的任务等。至于最后请求是成功还是失败,则是未知的。
该状态码表示客户端使用了代理服务器,代理服务器将客户端请求转发给服务端之后,被成功处理了。但代理服务器在将响应转发给客户端时,对原始响应内容进行了修改。
因此代理服务器也要将状态码(例如 200)修改为 203,来告知客户端这一情况,方便客户端做出相应的处理。注:203 响应可以被缓存。
该状态码表示请求已被成功处理,但服务端没有返回任何内容,指示客户端不需要更新当前的页面视图。
该状态码表示请求已被成功处理,服务端同样没有返回任何内容,但指示客户端需要更新当前的页面视图,例如清空表单内容或重置控件。
该状态码表示服务端已经成功处理了客户端发送的部分请求,主要用于以下场景。
分块请求:当客户端只请求资源的一部分,比如客户端使用 Range 请求头指定要下载文件的特定部分时,服务端会使用 206 Partial Content 响应。
断点续传:在文件下载过程中,如果下载被中断(例如因为网络问题),那么恢复正常时,客户端可以只请求未下载的部分。服务端对这种请求的响应就是 206 Partial Content,允许客户端继续从中断的地方下载,而不是重新开始。
流媒体:在流媒体应用中,客户端可能只请求媒体文件的一小部分,以便快速加载和播放,服务端对这种请求的响应也使用 206 Partial Content。
响应头信息:在返回 206 Partial Content 时,服务端会包含有关响应内容的信息,如 Content-Range 头部,这个头部指明了返回的部分内容在整个资源中的范围。
减少数据传输:使用 206 Partial Content 可以减少网络带宽的使用,因为它允许客户端仅请求和下载所需的数据部分。
206 Partial Content 状态码是一个高效处理大型资源请求的重要机制,特别是在网络条件不稳定或资源非常大的情况下,它可以显著提高数据传输的效率和可靠性。
该状态码用于 WebDAV 协议,当一个客户端请求对多个资源产生作用时,服务端会以 XML 的形式返回多个资源的状态,此时状态码为 207。
所以 207 Multi-Status 状态码在处理操作多个资源的请求时非常有用,特别是在 WebDAV 等分布式文件系统中,它提供了一种高效且灵活的方式来同时报告多个资源的状态。
208 Already Reported
该状态码通常和 207 一起使用,在 WebDAV 中,一个操作可能涉及多个资源,而这些资源可能又包含在不同的集合中。通过使用 208 Already Reported,服务端能够高效地表示哪些资源已经被处理,从而避免在多状态响应中重复报告。
3xx 系列的状态码属于重定向类别,用于告知客户端资源的获取方式已经改变,需要采取额外动作以完成请求。
比如访问一个已经废弃的链接,服务端就会返回 3xx 状态码,并在响应头的 Location 字段中指定新链接。客户端发现状态码为 3xx 之后,就会自动重定向到 Location 中指定的新链接。
另外在 RFC2068 中,规定客户端重定向次数不应超过 5 次,以防止死循环。
当请求的资源有多种表示时,服务端会返回 300,并提供一个资源列表,让客户端自行选择。由于缺乏明确的细节,因此该状态码不常用。
表示请求的资源已经被永久移动到了一个新的位置,该状态码的使用场景如下。
永久性重定向:当服务端返回 301 Moved Permanently 响应时,它表明请求的资源已经永久地移动到了由 Location 字段指定的 URL,未来所有对该资源的请求都应该使用这个新的URL。
更新书签和链接:301 状态码告诉客户端(如浏览器或搜索引擎)更新其链接或书签。对于搜索引擎优化(SEO)来说,这意味着应将原先页面的权重转移给新的 URL。
搜索引擎优化:在SEO的背景下,使用 301 Moved Permanently 是管理网站结构变化的最佳实践。它有助于维持旧 URL 的搜索排名和信誉,并将其传递给新 URL。
重定向方法:与临时重定向(如 302 Found 或 307 Temporary Redirect)不同,301 是永久性的。这告诉客户端在未来的所有请求中都应使用新的 URL,而不是临时性地查找资源。
表示请求的资源临时位于不同的 URL,该状态码的使用场景如下。
临时性重定向:当服务端返回 302 Found 响应时,它表明请求的资源现在暂时位于由 Location 头部指定的不同 URI 中。与 301 Moved Permanently 不同,302 Found 表示这种重定向只是暂时的。
原始 URL 保持有效:服务端期望客户端在未来的请求中继续使用原始的 URL,这意味着临时重定向后,原始 URL 仍然被视为有效。
搜索引擎处理:对于搜索引擎优化(SEO)来说,由于 302 Found 指示的是临时重定向,搜索引擎通常保持对原始 URL 的索引,而不是转移到新的地址。
其它用途:302 Found 也可以用于在网站维护期间或在进行 A/B 测试时,重定向到不同的 URL,同时保持原 URL 的有效性。
该状态码表示请求资源的响应需要通过另一个 URI 获取,并且要通过 GET 方法访问该 URI。
当服务端处理完 POST 请求(如表单提交)后,它可以发送 303 See Other 状态码,告诉客户端通过 GET 方法从指定的 URI 获取资源或信息,这样做可以防止刷新页面时重新提交表单。
所以 303 See Other 状态码在处理特定类型的 Web 请求(尤其是表单提交)并进行安全重定向时非常有用,它通过强制将后续请求的方法改为 GET,防止了表单重复提交这类问题。
该状态码表示从上次请求后,请求的资源未发生更改,因此客户端可以继续使用其缓存的版本。
关于资源缓存,这里解释一下。当服务端返回的响应中包含以下字段,代表资源可以被缓存。
Cache-Control:这是最重要的缓存头部之一,它可以设置多种指令来控制资源的缓存行为。如 max-age 指定资源可以缓存多久,no-cache 和 no-store 指示不缓存资源等。
关于 no-cache 和 no-store,虽然都表示不缓存资源,但它们之间还是有一些区别的。
Expires:该头部提供一个日期,该日期之后资源被认为过期。如果提供了 Cache-Control,那么 Expires 头部通常会被忽略。
Last-Modified:指示资源最后被修改的时间,客户端可以在后续的请求中使用 If-Modified-Since 头部来检查自该日期以来资源是否被修改。
ETag:提供资源的特定版本的标识,客户端可以在后续请求中使用 If-None-Match 头部,带上这个标签来检查资源是否有更新。
当客户端拥有某资源的缓存副本,并通过发送一个条件性请求(通常包含 If-Modified-Since 或 If-None-Match)来检查资源是否更新时,如果资源未更新,服务端就会返回 304 Not Modified。这意味着客户端无需下载该资源,可以使用其缓存的副本,否则将返回 200 OK 和新的资源。
因此和其它 HTTP 响应不同,304 Not Modified 响应通常不包含响应体,这是因为实际的内容没有更改,不需要重新传输。
304 有助于减少不必要的网络带宽使用,因为它避免了重新下载未更改的资源。所以 304 常用于网页和 Web 应用中,以优化性能,例如浏览器可能缓存网站的静态资源,并在后续访问时使用 If-Modified-Since 头部来检查这些资源是否已更新。
总的来说,304 Not Modified 状态码在管理 Web 资源缓存方面发挥着重要作用,减少了不必要的网络流量和加载时间,从而提高了网站或 Web 应用的性能,特别是对于那些需要频繁检索大量静态资源的网站。
注:305 和 306 已经被废弃了,这里简单了解一下即可。
305 和 306 在现如今的网络请求中不会遇到,因此简单带过,我们直接看 307。
首先 307 和 302 的作用相同,都表示临时性重定向,即要访问的资源临时移动到了另一个 URI 上,但在 HTTP 方法的处理方面,两者有所差异。
307 Temporary Redirect 要求客户端在后续的重定向请求中使用与原始请求相同的 HTTP 方法。例如原始请求是一个 POST 请求,那么在重定向后,客户端也必须使用 POST 方法发送到新的 URI。
而 302 Found 最初设计时也要求客户端保持相同的请求方法,但在实际使用中,许多客户端(如浏览器)会将后续的重定向请求改为 GET 方法,即使原始请求是 POST 或其它方法。虽然这种行为与 HTTP/1.1 规范不符,但已经成为事实上的标准。
所以 302、303、307 都表示临时性重定向:
308 和 301 是类似的,都表示永久性重定向,但 301 可能会导致请求方法从 POST 转变为 GET,而 308 则明确要求请求方法保持不变。
以上就是 3xx 系列的状态码,它们使得资源的迁移、缓存、优化更加灵活和有效,是网络基础设施中不可或缺的一部分,帮助网站和应用程序管理资源的更改和更新。
4xx 系列的 HTTP 状态码表示客户端错误,这些状态码指出请求中有错误,导致服务端无法或不会处理该请求。
400 Bad Request
该状态码表示由于客户端错误,服务端无法处理请求,主要在以下情况发生。
400 Bad Request 是一个通用的错误响应,表明服务端因客户端的错误而无法处理请求。这要求开发者对请求进行仔细检查和调整,所以正确的请求格式、有效的数据和合适的编码是避免这种错误的关键。
401 Unauthorized
该状态码表示请求未被服务端处理,因为它缺少有效的身份认证,主要在以下情况触发:
需要注意的是,Unauthorized 这个单词的意思是未授权,而不是未认证,所以用它来描述 401 就不太准确。关于认证和授权,这两个概念容易让人混淆,我们解释一下。
认证(Authentication)就是验证当前用户的身份是否合法的过程,比如指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就打卡成功。像用户名密码登录、邮箱发送登录链接、手机接收验证码等等都属于互联网中的常见认证方式,只要你能收到验证码,就默认你是账号的主人。认证主要是为了保护系统的隐私数据与资源。
授权(Authorization)则是谁(who)对什么(what)进行了什么操作(how),和认证不同,认证是确认用户的合法性,以及让服务端知道你是谁,而授权则是为了更细粒度地对资源进行权限上的划分。所以授权是在认证通过后,控制不同的用户访问不同的资源。
并且授权是双向的,可以是用户给服务端授权,也可以是服务端给用户授权。
因此 401 状态码表示的是客户端未认证,但 Unauthorized 的中文翻译是未授权。
该状态码表示服务端理解客户端的请求,但因客户端没有访问请求资源的权限,所以服务端拒绝执行该请求,即使请求是有效的。
和 401 不同,返回 401 是因为请求缺少有效的身份凭证,导致服务端不知道客户端的身份。而 403 意味着服务端知道客户端是谁,只是它没有足够的权限来触发请求的执行,因此拒绝访问。
所以回顾一下认证和授权:
我们发现 401 Unauthorized 改成 401 Unauthenticated 会更合理一些,而 403 Forbbiden 对应的才是 Unauthorized,因为没有访问资源的权限不就是未授权吗,即客户端未被授予访问指定资源的权限。
认证和授权的中文很好区分,但英文就容易混淆了,因为长得比较像。
补充:为了安全起见,服务端可能会故意使用 404 Not Found 而非 403 Forbidden 来隐藏资源的存在,避免暴露敏感信息。
这个应该是最知名的状态码了,它表示服务器找不到请求的资源。当客户端请求的资源在服务器上不存在或者未被发现,就会返回 404。
出现 404,主要是以下几个原因:
在 Web 开发中,我们通常也会自定义 404,比如你要找的页面去火星了······,等等之类的。
虽然 404 通常被视为错误,但合适的处理和用户友好的错误页面可以在很大程度上改善用户的浏览体验。对于网站管理员和开发者而言,妥善管理和最小化 404 错误是提高网站质量和用户满意度的重要部分。
该状态码表示客户端以错误的 HTTP 方法去访问请求的资源,比如一个资源只接受 GET 和 POST 请求,但客户端尝试使用 PUT 或 DELETE。
而当返回 405 Method Not Allowed 时,服务端通常会在响应头中包含一个 Allow 字段,列出对该资源有效的请求方法。例如,Allow: GET, POST。
该状态码表示服务端无法提供与客户端在请求的 Accept 头字段中指定的内容特征相匹配的响应,换句话说,服务端无法生成客户端期望的响应格式。
比如客户端在 Accept 头部中指定了一种服务端不支持的媒体类型(如 application/xml)。
另外当客户端请求的语言(通过 Accept-Language 指定)或编码(通过 Accept-Encoding 指定)服务端无法提供时,也可能返回此状态码。
对于开发者来说,这个状态码强调了内容协商机制的重要性,即服务端需要根据客户端的要求提供不同格式的响应。对于终端用户来说,遇到 406 错误通常意味着他们的客户端(例如 Web 浏览器或应用)发送了服务端无法满足的请求。在某些情况下,用户可以尝试更改请求的格式。
与 401 类似,但它表示请求需要通过代理发送,而客户端没有通过代理服务器的认证。
以上是 4xx 系列比较常见的状态码,还有一些不常见的,我们简单罗列一下。
406 指的是服务端无法生成客户端接受的响应类型;
415 指的是服务端不支持客户端上传的文件类型;
4xx 系列的状态码提供了服务端对于特定错误情况的反馈,帮助客户端开发者诊断问题并采取相应措施。
5xx 系列的 HTTP 状态码表示服务器错误,这些状态码表明客户端的请求本身可能没有问题,但由于服务器遇到问题而无法完成请求。
这是最常见的服务器错误状态码,表明服务端遇到了一个意外情况,阻止了其完成请求。比如服务端代码报错了,但又没有异常捕获,这个时候会直接抛出 500。
该状态码表示服务器不支持当前请求所需要的功能,当服务器无法识别请求方法,并且无法支持其对任何资源的请求时,可能会返回这个状态码。
当服务器作为网关或代理,从上游服务器收到无效响应时,会返回此状态码。相信 502 大家也经常会遇到,伴随而来往往是 NGINX。
NGINX 将请求转发给后端服务,但后端服务报错了,没有提供正常响应,这时 NGINX 就会返回 502 给客户端。因此当你看到 502 时,就应该知道 NGINX 代理正常工作,但它背后的服务出错了。
该状态码表明服务器目前无法使用(由于超载或停机维护),通常这只是暂时状态。
当服务器作为网关或代理,没有及时从上游服务器收到请求时,会返回这个状态码。
该状态码表明服务器不支持请求中使用的 HTTP 协议版本。
以上就是 5xx 系列常见的状态码,这些状态🐴表示客户端的请求正常,但问题出现在服务端。
以上就是 HTTP 状态码,它是 Web 通信的核心组成部分,为理解客户端和服务端之间的交互提供了基础。这些状态码提供了关于请求是否成功,以及如果不成功,原因是什么的关键信息。
了解每个状态码的含义,可以让我们在 Web 开发中迅速定位到问题。
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
添加我为好友,拉您入交流群!
请使用微信扫一扫!