当服务端返回 HTTP 响应时,会带有一个状态码,用于表示特定的请求结果。比如 HTTP/1.1 200 OK,里面的 HTTP/1.1 表示协议版本,200 则是状态码,OK 则是对状态码的描述。
由协议版本、状态码、描述信息组成的行被称为起始行,服务端返回的响应报文中的第一行便是它,然后是响应头和响应体。
首先状态码由三位数字组成,按照第一个数字的不同,可分为五个类别,每个类别的含义如下
-
1xx(信息响应):这类状态码表示临时响应,意思是告诉客户端,服务端已收到部分请求,请你继续发送剩余的部分;
-
2xx(成功):这类状态码表示客户端的请求已被成功处理;
-
3xx(重定向):这类状态码表示为了完成请求,需要进一步的操作,比如跳转到新位置;
-
4xx(客户端错误):这类状态码表示请求不合法,比如操作一个没有权限的资源或者不存在的资源等等;
-
5xx(服务端错误):这类状态码表示服务端内部在处理请求时出现错误,比如服务端的代码报错;
3xx 系列的状态码属于重定向类别,用于告知客户端资源的获取方式已经改变,需要采取额外动作以完成请求。
比如访问一个已经废弃的链接,服务端就会返回 3xx 状态码,并在响应头的 Location 字段中指定新链接。客户端发现状态码为 3xx 之后,就会自动重定向到 Location 中指定的新链接。
另外在 RFC2068 中,规定客户端重定向次数不应超过 5 次,以防止死循环。
300 Mutiple Choices
当请求的资源有多种表示时,服务端会返回 300,并提供一个资源列表,让客户端自行选择。由于缺乏明确的细节,因此该状态码不常用。
301 Moved Permanently
表示请求的资源已经被永久移动到了一个新的位置,该状态码的使用场景如下。
永久性重定向:当服务端返回 301 Moved Permanently 响应时,它表明请求的资源已经永久地移动到了由 Location 字段指定的 URL,未来所有对该资源的请求都应该使用这个新的URL。
更新书签和链接:301 状态码告诉客户端(如浏览器或搜索引擎)更新其链接或书签。对于搜索引擎优化(SEO)来说,这意味着应将原先页面的权重转移给新的 URL。
搜索引擎优化:在SEO的背景下,使用 301 Moved Permanently 是管理网站结构变化的最佳实践。它有助于维持旧 URL 的搜索排名和信誉,并将其传递给新 URL。
重定向方法:与临时重定向(如 302 Found 或 307 Temporary Redirect)不同,301 是永久性的。这告诉客户端在未来的所有请求中都应使用新的 URL,而不是临时性地查找资源。
302 Found
表示请求的资源临时位于不同的 URL,该状态码的使用场景如下。
临时性重定向:当服务端返回 302 Found 响应时,它表明请求的资源现在暂时位于由 Location 头部指定的不同 URI 中。与 301 Moved Permanently 不同,302 Found 表示这种重定向只是暂时的。
原始 URL 保持有效:服务端期望客户端在未来的请求中继续使用原始的 URL,这意味着临时重定向后,原始 URL 仍然被视为有效。
搜索引擎处理:对于搜索引擎优化(SEO)来说,由于 302 Found 指示的是临时重定向,搜索引擎通常保持对原始 URL 的索引,而不是转移到新的地址。
其它用途:302 Found 也可以用于在网站维护期间或在进行 A/B 测试时,重定向到不同的 URL,同时保持原 URL 的有效性。
307 Temporary Redirect
注:305 和 306 已经被废弃了,这里简单了解一下即可。
-
305 Use Proxy:该状态码表示请求的资源必须通过代理访问,代理的地址由 Location 字段给出。
-
306 Switch Proxy:该状态码表示后续请求应使用不同的代理来访问资源。
305 和 306 在现如今的网络请求中不会遇到,因此简单带过,我们直接看 307。
首先 307 和 302 的作用相同,都表示临时性重定向,即要访问的资源临时移动到了另一个 URI 上,但在 HTTP 方法的处理方面,两者有所差异。
307 Temporary Redirect 要求客户端在后续的重定向请求中使用与原始请求相同的 HTTP 方法。例如原始请求是一个 POST 请求,那么在重定向后,客户端也必须使用 POST 方法发送到新的 URI。
而 302 Found 最初设计时也要求客户端保持相同的请求方法,但在实际使用中,许多客户端(如浏览器)会将后续的重定向请求改为 GET 方法,即使原始请求是 POST 或其它方法。虽然这种行为与 HTTP/1.1 规范不符,但已经成为事实上的标准。
所以 302、303、307 都表示临时性重定向:
-
302 Found 的原始设计意图是重定向时使用的方法不变,但许多客户端(如浏览器)会默认使用 GET,当然也有客户端没有这么做。因此这就增加了模糊性,于是便有了 303 和 307;
-
303 See Other 明确指出客户端在重定向时应该使用 GET 方法,无论原始请求使用的是哪种方法。因此 303 可以确保在处理完 POST 请求(如表单提交)后引导浏览器加载一个新页面,并且刷新或后退操作不会再次提交表单;
-
307 Temporary Redirect 则明确指出重定向时,使用的请求方法要保持不变;
403 Forbidden
该状态码表示服务端理解客户端的请求,但因客户端没有访问请求资源的权限,所以服务端拒绝执行该请求,即使请求是有效的。
和 401 不同,返回 401 是因为请求缺少有效的身份凭证,导致服务端不知道客户端的身份。而 403 意味着服务端知道客户端是谁,只是它没有足够的权限来触发请求的执行,因此拒绝访问。
所以回顾一下认证和授权:
-
未认证是 Unauthenticated;
-
未授权是 Unauthorized;
我们发现 401 Unauthorized 改成 401 Unauthenticated 会更合理一些,而 403 Forbbiden 对应的才是 Unauthorized,因为没有访问资源的权限不就是未授权吗,即客户端未被授予访问指定资源的权限。
认证和授权的中文很好区分,但英文就容易混淆了,因为长得比较像。
补充:为了安全起见,服务端可能会故意使用 404 Not Found 而非 403 Forbidden 来隐藏资源的存在,避免暴露敏感信息。
404 Not Found
这个应该是最知名的状态码了,它表示服务器找不到请求的资源。当客户端请求的资源在服务器上不存在或者未被发现,就会返回 404。
出现 404,主要是以下几个原因:
-
用户输入了错误的 URL;
-
本来存在的资源被删除、移动或重命名,但却没有重定向;
-
服务器或网站的配置问题,导致无法访问特定资源;
在 Web 开发中,我们通常也会自定义 404,比如你要找的页面去火星了······,等等之类的。
虽然 404 通常被视为错误,但合适的处理和用户友好的错误页面可以在很大程度上改善用户的浏览体验。对于网站管理员和开发者而言,妥善管理和最小化 404 错误是提高网站质量和用户满意度的重要部分