HTTP 中的状态码

状态码,从字面意思可以看出是描述状态的代码。一般呢就是由3位数字组成的,

比较官方的解释就是:“用以表示网页服务器超文本传输协议响应状态的3位数字代码”,

其实关于状态码,在实际场景中是很常见的,比如打开了一个不存在的页面,弹出404Not Found;或者由于服务器的问题,返回503

▶ 为什么要了解状态码?

1、实际场景中,可能会遇到这种情况,比如你测试调用某个接口,结果返回500(这里是做假设),然后你以为你的代码写错了,不断找错,最后可能发现是服务器的错(比如没有开启某个端口)。但如果你要是看了我的文章,知道5XX是描述服务器错误的状态码,那你就可以不用花那么多时间纠错。

2、或许你没遇到过上面的情况,但是面试官可能会问你有关状态码的问题,比如

  • 说一下HTTP协议中503的状态?
  • 302和301状态码的区别?
  • HTTP中的XXX状态码代表着什么?

因此,了解状态码可以帮助我们在开发时,减少一些不必要的麻烦,或者可以避免我们在面试中因为不了解状态码而不知所言,废话不多说,进入正题。

正题


▶ 状态码的类别

我们先根据状态码的第一位数字进行分类,有以下5种类别:

||||

|---|---|---| | |类别|原因短语| |1XX|Informational(信息性状态码)|接收的请求正在处理| |2XX|Success(成功状态码)|请求正常处理完毕| |3XX|Redirection(重定向状态码)|需要进行附加操作以完成请求| |4XX|Client Error(客户端错误状态码)|服务器无法处理请求| |5XX|Server Error(服务端错误状态码)|服务器处理请求出错|

(其中1XX状态码不是很常见,这里不做描述)

▶ 状态码——200(OK)

显然,这是一个很常看到的状态码,一般我们只要能够正常访问网页,都会返回200

比如我们随便在谷歌搜索一个关键词,然后查看F12中的网络状态

可以发现,返回200状态码的响应报文所占比例还是挺大的

这里的200,就是用来告知我们(客户端)的请求被对方(服务端)正常处理啦,并且会根据请求方法的不同,判断是否返回资源

(比如使用GET请求时,对方(服务端)会将资源实体返回给我们(客户端);使用HEAD请求时,则不返回资源实体

个人认为,200是最常见的状态码(毕竟一般我们都是正常访问的),也是最容易理解的状态码

▶ 状态码——204(Not Content)

204状态码跟200有点类似,都是代表我们(客户端)的请求被对方(服务端)正常处理

区别在于对方(服务端)不会返回也不允许返回任何资源实体

还是以谷歌搜索为例,仔细发现,上图中除了大部分的200状态码,还有小部分的204状态码

点击204状态码的响应报文,可以发现并没有返回资源实体

204状态码使用场景:

一般在只需要从客户端往服务端发送信息,而对客户端不需要发送新信息内容的情况下使用

▶ 状态码——206(Partial Content)

"Partial"的意思就是“部分的,局部的”,从字面意思上可以理解为返回部分内容

比较官方的解释:

表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容

例子说明:

我们代表左边(客户端),对方代表右边(服务器)

假设我们(客户端)要请求某个学习资料.avi的后半部分(30001-60000),我们会说:

GET  /xxxxx/xxx.avi  HTTP/1.1
Host:  xxx.xx
Range:  bytes=30001-60000

对方(服务器)听到之后,意识到你只需要xxx.avi中30001-60000范围的部分,

给你回信,信中说道:

HTTP/1.1  206 Partial Content
Content-Length:  30000
Content-Range:  bytes 30001-60000
Content-Type:  video/mpeg

这时候,对方回信的内容会附带206 Partial Content状态码以及Content-Range: bytes 30001-60000资源范围

206状态码使用场景:

一般用于资源范围请求,如果我们只需要部分的资源,则对方会返回206状态码来说明成功返回部分资源

特殊情况:如果对方无法处理该服务请求时,则会返回200状态码以及全部资源

▶ 2XX状态码小结:

综上,我们可以明白2XX的响应结果表明请求被对方正常处理了

▶ 状态码——301(Moved Permanently)

"Moved Permanently"在有道翻译的解释为:

● 永久移动

● 客户试图访问的资源已移到新的永久位置

● 永久移除

比较官方的解释:

永久性重定向(重定向就是从某个URI跳转到新的URI)

该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI

(新的URI会在响应首部Location字段出现)

例子说明:

我在使用谷歌搜索时,会直接在浏览器中输入http://google.com,这时候如果观察F12中网络的变化,你会发现有一条返回301的响应信息

点击查看具体信息

图中标红的地址就是我们在地址栏中输入的地址

标蓝的地址就是对方告诉我们应该访问新的地址http://www.google.com/

这时候,浏览器接收到服务器返回的301状态码后,就会根据响应首部location字段的新地址(这里就是http://www.google.com)进行重新请求

301状态码的使用场景:

● 域名跳转,比如上述例子,将google.com跳转到www.google.com

● 旧URI已经失效,需要通知用户访问新URI,这时候可以使用301永久重定向,通知用户使用location字段的新地址进行访问

▶ 状态码——302(Moved Temporarily)

"Moved Temporarily"在有道翻译的解释为:

● 临时移动

比较官方的解释:

临时性重定向

该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问

302跟301比较类似,但注意301是永久性重定向,302是临时性重定向,什么意思呢?

在上面301的使用场景中,我们提到第二个场景,这时候的旧URI已经失效,用户无法继续访问,而302的场景跟301相反

旧URI还是可以使用,旧URI的资源只是临时被移动到新的URI中

例子说明:

淘宝大家都使用过吧,假如我登录账号查看我的淘宝购物车,我们先保存购物车中对应的URI

https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm?spm=a21bo.2017.1997525045.2.5af911d9xpHb6l

接下来在别的浏览器中打开上面的URI,同时打开F12观察网络状况

服务器返回302状态给我们了,这是因为这个URI原本应该是打开购物车的,但是由于我们在别的浏览器打开,没有登录信息

打开该条响应信息

会在location首部字段中返回新的URI,通知浏览器临时跳转到新的URI中,即登录页面的URI,告知我们需要登录才可以查看购物车

302状态码的使用场景:

综上所述,我们可以推出302状态码可以应用在网页登录信息失效时临时跳转到新的URI

又或者,网站中有临时的页面需要跳转,而原来的页面需要保留时,可以返回302状态码以起临时重定向的作用

▶ 状态码——303(See Other)

比较官方的解释:

该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源

303跟302相比,其实功能都是一样的,都是起到临时重定向的作用,

唯一的区别是303状态码明确表示客户端应当采用GET方法获取资源

303状态码的使用场景:

跟302一样,只是这里希望我们使用GET方法来获取资源

小Tips:

当301、302、303响应状态码返回时,几乎所有浏览器都会把POST改成GET,并删除请求报文内的主题,之后请求会自动再次发送。

301、302的标准中是禁止将POST方法改变成GET方法的,但实际使用时大家都会这么做。

▶ 状态码——304(Not Modified)

"Not Modified"

● 未修改

比较官方的解释:

该状态码表示客户端发送附带条件的请求(指GET方法请求报文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部)时,服务端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)。

例子说明:

现在有个场景,我们第一次打开淘宝时,观察到标红区域是返回200状态码的

按下F5刷新一下淘宝

观察一下标红区域返回的状态码,从200变成了304

按下Ctrl+F5再次刷新淘宝

观察到该状态码又变成了200

(这里的Ctrl+F5是强制刷新,会清理缓存,而F5只是将当前页面进行刷新,不会清理缓存)

为什么会第二次刷新时会变成304呢?我们从第一次打开淘宝说起

第一次打开淘宝时,search-suggest-history-iframe会返回一个Etag标志给我们,Etag的值为W/"2aba-1602480f459",同时返回200状态码(ETag是用来标识服务器中的每份资源,假设用001来标识资源A,用032来标识资源B)

我们观察到服务器返回一个Cache-Control字段,该字段让我们进行对search-suggest-history-iframe缓存60s(标蓝字段)

第二次打开淘宝时,我们客户端会自动发送一个If-None-Match字段,这个字段的值就是Etag的值W/"2aba-1602480f459"

服务器接收到第二次请求时,发现我们给了它一个If-None-Match参数,然后将参数中的值,也就是W/"2aba-1602480f459"

跟服务器中的ETag进行对比,如果相同,则返回304状态码,表示服务器的资源未修改,让我们继续使用本地缓存

如果If-None-Match的值跟ETag的值不相等,则会返回200状态码,表示服务器的资源已经修改,这时候会返回新的资源给我们

类比生活场景:

304状态码可能会比较难理解,因为涉及到缓存以及ETag等知识点,如果实在不是很理解ETag,

那我们可以把它当作现实世界中的门牌,服务器就是一家酒店,

我们(客户)需要去某个房间时,首先到前台咨询是否有我们想要的房间(发送请求),

前台告诉我们空房间门牌号为101并给我们101门卡(ETag),这时我们就可以去房间了(访问资源)。

我们把行李搬进房间后去外面吃饭,这时候再回来酒店的话(第二次访问),我们可以直接通过门卡(If-None-Match的值)去房间,而不用再去咨询前台了(相当于做了缓存)

当然,实际情况可能会更加复杂,这里只是做一个简单的类比,方便大家理解。

304状态码的使用场景:

对一些频繁访问的静态文件,比如html、css、js等,可以使用304做缓存,从而减少服务器的负担,提升网站访问速度

▶ 状态码——307(Temporary Redirect)

"Temporary Redirect"

● 临时重定向

比较官方的解释:

临时性重定向

该状态码与302有着相同的含义。尽管302标准禁止POST变换成GET,但实际使用时大家并不遵守

307会遵照浏览器标准,不会从POST变成GET,但不同的浏览器可能会出现不同的情况

307状态码的使用场景:

跟302一样,只是会要求我们使用POST方法来重定向Location字段的URI

▶ 3XX状态码小结:

综上,其实除了304状态码跟重定向没什么关系,其余的状态码都跟重定向相关

▶ 状态码——400(Bad Request)

“Bad Request”

● 请求错误

比较官方的解释:

该状态码表示请求报文中存在语法错误

这个很好理解,一般发生400错误的话,建议检查一下请求的内容再次发送请求,

其次,浏览器会像200状态码一样对待该状态码。

例子说明:

▶ 状态码——401(Unauthorized)

“Unauthorized”

● 非法的

● 未被授权的

比较官方的解释:

该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。

例子说明:

以BASIC认证作为例子

我们直接访问http://xxx.xx/login.html时,服务器返回401,并携带WWW-Authenticate首部字段询问用户信息

这时候会弹出登录窗口,提示我们输入用户名和密码,这里假设用户名为user,密码为123

用户和密码中间用分号:隔开,再经过Base64方式编码(user:123  →  dXNlciUzQTEyMw==)

将编码后的字符串写入请求首部字段Authorization中并发送给服务器

若认证成功,则返回200;若认证失败,则还是返回401

401状态码的使用场景:

使用HTTP认证时,可以通过401寻求用户的登录情况或者返回用户信息是否认证成功

▶ 状态码——403(Forbidden)

“Forbidden”

● 被禁止的

● 严禁的

比较官方的解释:

该状态码表明对请求资源的访问被服务器拒绝了

403状态码的例子就不再赘述,大家可以直接看它的使用场景,也是挺好理解的

403状态码的使用场景:

● IP被服务器拉黑

● 身份认证时密码出错

● 访问目录的权限不够

● 等等等等

▶ 状态码——404(Not Found)

"Not Found"

● 未找到

比较官方的解释:

该状态码表明服务器上无法找到请求的资源。

例子说明:

这个还是比较常见的吧,我们打开某个网站,结果弹出404,告诉我们找不到这个网址

比如下方的https://www.google.com/xxx.xx

现在国内一些网站在弹出404时,会顺带一张寻人启事,例如打开https://www.qq.com/xxx.xx

404状态码的使用场景:

客户端输入一个不存在的URI,服务端返回404

▶ 4XX状态码小结:

综上,我们可以找到一个规律,那就是返回4XX的状态码一般都是我们客户端出现错误的原因

比如请求语法错误(400)、需要认证(401)、权限不够(403)、输入错误URI(404)

▶ 状态码——500(Internal Server Error)

"Internal Server Error"

● 内部服务器错误

这个情况我遇到过,因为返回500找了好久的错,最终记录在下面这篇博客中,感兴趣的可以看看

【PHP】在阿里云服务器Ubuntu邮箱PHPMailer使用出现500的问题

比较官方的解释:

该状态码表明服务器端在执行请求时发生了错误,也有可能是Web应用存在的bug或某些临时的故障

例子说明:

有这么一个场景,我们需要实现一个自动发送邮箱的功能,该功能需要配合SMTP(简单邮件传送协议,Simple Mail Transfer Protocol)

这时我们的代码是完全没问题的,可就是一直发送不了邮箱,一直返回500状态码

最后发现是因为服务器没有开启25端口(SMTP的默认端口是25),导致SMTP服务无法正常进行

返回500状态码是由于服务器内部发生错误了,那什么时候会返回500呢

500状态码的使用场景:

● 服务端代码出错(包括后端代码,比如PHP、Java;数据库代码等)

● 未开放指定端口

▶ 状态码——503(Service Unavailable)

"Service Unavailable"

● 服务不可用

● 无法提供服务

比较官方的解释:

该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

例子说明:

这个情况也比较常见,比如抢课时服务器崩溃,如下图,有大量的用户同时请求,服务器承载不住了

503状态码的使用场景:

● 服务器超载

● 服务器停机维护

▶ 5XX状态码小结:

这个跟4XX的错误是相反的,4XX是由于客户端错误引起的,而5XX是服务器本身发生错误引起的

HTTP 中的状态码的相似文章

凛冬将至什么水平,2022凛冬之时三年经验前端面经分析理解vue中的diff算法,Vue原理解析(八):一起搞明白令人头疼的diff算法分析Vue 的生命周期之间到底做了什么事清?(源码详解,带你从头梳理组件化流程)分析金三银四,我先面为敬了(腾讯、美团、商汤科技等七家大厂面试有感)分析浏览器的渲染原理及优化方式,浏览器层合成与页面渲染优化分析 连八股文都不懂还指望在前端混下去么分析【7k长文,一次到位】前端八股文再来一遍🧐(图解 + 总结)分析2021年前端各大公司都考了那些手写题(附带代码)分析vue中$router与$route的区别,可能比文档还详细--VueRouter完全指北分析【建议👍】再来40道this面试题酸爽继续(1.2w字用手整理)分析