NodeJs 第二十四章(HTTP状态码)

229 阅读17分钟

前言

前面学习了Express,jwt并且成功的写完了登录注册接口,但是这里我们返回的http状态码太随意了。这篇文章带你学习http状态码让我们的响应更加规范。

HTTP 状态码的分类基础

HTTP 状态码由三位数字构成,第一位数字是分类的关键标识,它将状态码划分为五大类别,每一类都有着独特的使命和含义,而后两位数字则进一步细化了具体的状态信息。

(一)1xx:信息性状态码

这类状态码相对较为少见,主要用于在客户端和服务器之间传递一些临时的信息,表明请求已被接收,需要进一步处理。

1. 100 Continue

在客户端需要发送大量数据时,为了避免不必要的数据传输,它会先发送一个带有 Expect: 100-continue 头部的请求。服务器收到这个请求后,如果认为可以接收后续的请求体,就会返回 100 Continue 状态码。例如,在一个文件上传系统中,客户端准备上传一个大型视频文件。在发送文件内容之前,客户端先发送一个请求询问服务器是否准备好接收。如果服务器返回 100 Continue,客户端就会继续发送文件数据。这种机制可以有效避免在服务器无法处理请求时,客户端仍然发送大量数据,从而节省网络带宽和服务器资源。

2. 101 Switching Protocols

当客户端和服务器需要协商切换协议时,就会用到 101 Switching Protocols 状态码。最典型的应用场景是从 HTTP 协议升级到 WebSocket 协议。WebSocket 协议允许在浏览器和服务器之间进行实时双向通信,适用于需要实时更新数据的应用,如在线聊天、实时游戏等。当客户端向服务器发送升级协议的请求时,服务器如果支持并同意升级,就会返回 101 Switching Protocols 状态码,随后双方开始使用新的协议进行通信。

(二)2xx:成功状态码

这是我们最乐于见到的一类状态码,它表明请求已经成功被服务器接收、理解并处理。不同的 2xx 状态码对应着不同的成功场景。

1. 200 OK

作为最常见的成功状态码,200 OK 表示请求正常处理完毕,服务器返回了客户端所请求的数据。在 Web 开发中,大量的 GET 请求都会得到 200 OK 的响应。例如,当用户在浏览器中输入一个网页的 URL 并按下回车键时,浏览器会向服务器发送一个 GET 请求。如果服务器能够正常找到并返回该网页的 HTML 内容,就会附带 200 OK 状态码。此外,对于一些简单的 API 请求,如获取用户信息、查询商品列表等,成功响应时也通常返回 200 OK。

2. 201 Created

当客户端发送 POST 请求用于创建新资源时,如果服务器成功创建了该资源,就会返回 201 Created 状态码。同时,响应头中通常会包含一个 Location 字段,指向新创建资源的 URL。以一个电商系统为例,当用户提交一个新订单时,服务器会对订单信息进行处理并将其存储到数据库中。如果订单创建成功,服务器会返回 201 Created 状态码,并在 Location 字段中提供该订单的详细信息页面的 URL,方便客户端后续访问。

3. 202 Accepted

该状态码表示服务器已经接收了请求,但尚未开始处理。这种情况通常出现在异步处理的场景中,服务器需要花费一定的时间来完成请求的处理。例如,在一个邮件发送系统中,用户提交了一封邮件的发送请求。由于邮件发送可能涉及到多个步骤,如邮件内容的格式化、邮件服务器的连接等,服务器可能无法立即完成发送操作。此时,服务器会返回 202 Accepted 状态码,表示已经接收到请求,会在后台进行邮件发送操作。客户端可以通过后续的查询接口来获取邮件发送的结果。

4. 204 No Content

当请求已经成功处理,但响应中不需要返回任何内容时,服务器会返回 204 No Content 状态码。常见于执行某种操作后不需要返回数据的情况,比如用户删除一个记录。在一个博客系统中,当用户删除一篇博客文章时,服务器处理完删除请求后,会返回 204 No Content 状态码,告知客户端删除操作已成功完成,但不返回任何额外的数据。

(三)3xx:重定向状态码

3xx 状态码表示客户端需要采取进一步的操作来完成请求,通常是重定向到另一个 URL。重定向可以是永久的,也可以是临时的,不同的状态码对应着不同的重定向类型。

1. 301 Moved Permanently

表示请求的资源已经永久移动到了新的 URL。浏览器会记住这个重定向,下次请求时会直接访问新的地址。这种状态码常用于网站改版、域名变更等情况。例如,一个知名的新闻网站由于业务发展需要,将域名从 http://olddomain.com 迁移到 http://newdomain.com。为了保证用户能够顺利访问新网站,服务器会对旧域名的请求返回 301 Moved Permanently 状态码,并在响应头中设置新的 URL。搜索引擎在抓取网页时,也会根据 301 状态码更新网页的索引,将旧 URL 的权重转移到新 URL 上。

2. 302 Found

该状态码表示资源临时移动,浏览器下次请求还是会访问原来的 URL。通常用于临时的业务调整或测试场景。比如,网站正在进行部分页面的维护,服务器会将访问这些页面的请求临时重定向到一个维护提示页面。当维护完成后,服务器可以恢复正常的响应,客户端下次请求仍然会访问原来的页面。需要注意的是,302 状态码在某些情况下可能会导致搜索引擎对页面的索引出现问题,因此在使用时需要谨慎。

3. 303 See Other

与 302 Found 类似,但 303 See Other 明确表示客户端应该使用 GET 方法访问重定向的 URL。当客户端发送 POST 请求后,服务器需要将客户端重定向到另一个页面时,通常会使用 303 See Other 状态码。例如,在一个在线购物系统中,用户提交了一个订单支付请求。服务器处理完支付逻辑后,返回 303 See Other 状态码,并将客户端重定向到一个支付结果页面。客户端会使用 GET 方法访问该页面,以避免重复提交支付请求。

4. 304 Not Modified

用于缓存机制,当客户端发送请求时会带上 If-Modified-Since 或 If-None-Match 等头部信息,服务器根据这些信息判断资源是否有更新。如果资源没有更新,服务器会返回 304 Not Modified 状态码,客户端可以使用本地缓存的资源,从而减少数据传输,提高响应速度。例如,浏览器在访问一个图片资源时,会记录该图片的最后修改时间。下次再次请求该图片时,浏览器会在请求头中带上 If-Modified-Since 字段,服务器根据这个时间判断图片是否有更新。如果没有更新,服务器返回 304 Not Modified 状态码,浏览器直接使用本地缓存的图片。

(四)4xx:客户端错误状态码

4xx 状态码表示客户端发送的请求有错误,无法被服务器所识别或处理。这类状态码通常是由于客户端的请求格式不正确、缺少必要的身份验证信息或请求的资源不存在等原因导致的。

1. 400 Bad Request

通常表示客户端发送的请求语法错误,服务器无法理解。可能是请求参数格式不正确、请求头缺失等原因造成的。例如,在一个 API 接口中,要求客户端传递一个 JSON 格式的用户信息,其中包含 name 和 age 字段。如果客户端传递的 JSON 数据格式错误,如缺少引号、字段名拼写错误等,服务器就会返回 400 Bad Request 状态码,并可以在响应中包含具体的错误信息,帮助客户端进行调试。

2. 401 Unauthorized

表示请求需要进行身份验证,客户端没有提供有效的身份凭证。在访问需要登录的资源时,服务器会返回 401 Unauthorized 状态码,并在响应头中包含 WWW-Authenticate 字段,提示客户端进行身份验证的方式。常见的身份验证方式有基本认证(Basic Authentication)和令牌认证(Token Authentication)。例如,在一个企业内部的管理系统中,用户需要输入用户名和密码进行登录。如果用户未登录就尝试访问受保护的页面,服务器会返回 401 Unauthorized 状态码,提示用户进行登录操作。

3. 403 Forbidden

表示服务器理解请求客户端的请求,但是拒绝执行此请求。这可能是因为客户端没有权限访问该资源,即使提供了有效的身份验证信息也不行。例如,某些内部资源只有特定的用户组才能访问,普通用户访问时会收到 403 Forbidden 状态码。在一个银行系统中,只有管理员用户才能访问客户的敏感信息,普通用户即使登录成功,也无法访问这些信息,服务器会返回 403 Forbidden 状态码。

4. 404 Not Found

这是最常见的客户端错误状态码之一,表示请求的资源在服务器上不存在。可能是用户输入的 URL 错误,或者资源已经被删除。当用户在浏览器中输入一个不存在的页面地址时,就会看到 404 Not Found 页面。网站通常会定制 404 页面,提供一些友好的提示信息,如建议用户检查 URL 是否正确、提供网站导航等,以提升用户体验。

5. 405 Method Not Allowed

表示客户端使用的请求方法(如 GET、POST、PUT 等)不被服务器允许。例如,某个 API 接口只支持 POST 请求,用于创建新的资源。如果客户端使用 GET 方法访问该接口,服务器会返回 405 Method Not Allowed 状态码,并在响应头中包含 Allow 字段,列出允许的请求方法。这样客户端就可以根据 Allow 字段的信息,使用正确的请求方法重新发起请求。

6. 406 Not Acceptable

当客户端请求的资源的内容类型不符合服务器能够提供的内容类型时,服务器会返回 406 Not Acceptable 状态码。客户端可以在请求头中使用 Accept 字段指定希望接收的内容类型,如 application/jsontext/html 等。如果服务器无法提供客户端所要求的内容类型,就会返回 406 状态码。例如,客户端请求一个资源时,指定只接受 application/xml 格式的响应,但服务器只能提供 application/json 格式的响应,此时服务器会返回 406 Not Acceptable 状态码。

(五)5xx:服务器错误状态码

5xx 状态码表示服务器在处理请求的过程中出现了错误,无法完成请求。这类状态码通常是由于服务器内部的代码错误、配置问题或资源耗尽等原因导致的。

1. 500 Internal Server Error

这是最通用的服务器错误状态码,表示服务器内部发生了未知的错误,无法完成请求。可能是服务器端代码出现了异常、数据库连接失败等原因造成的。在开发过程中,当服务器代码出现未捕获的异常时,就会返回 500 Internal Server Error 状态码。例如,在一个使用 Python Flask 框架开发的 Web 应用中,如果代码中存在一个除零错误,当客户端请求触发该代码时,服务器就会返回 500 状态码。服务器端通常会记录详细的错误日志,以便开发者进行排查和修复。

2. 502 Bad Gateway

通常出现在服务器作为网关或代理时,从上游服务器收到了无效的响应。例如,一个 Web 应用通过反向代理服务器访问后端的 API 服务,如果 API 服务器出现故障,反向代理服务器就会返回 502 Bad Gateway 状态码。反向代理服务器在接收到客户端的请求后,会将请求转发给后端的 API 服务器。如果 API 服务器无法正常响应,如返回了一个格式错误的响应或者超时未响应,反向代理服务器就会认为收到了无效的响应,从而返回 502 状态码。

3. 503 Service Unavailable

表示服务器目前无法处理请求,可能是因为服务器过载或正在进行维护。当服务器的负载过高,无法及时处理新的请求时,会返回 503 Service Unavailable 状态码。同时,服务器可以在响应头中包含 Retry-After 字段,告知客户端在多长时间后可以重试请求。例如,在一个电商网站的促销活动期间,大量用户同时访问网站,服务器可能会因为负载过高而返回 503 状态码。服务器可以设置 Retry-After 字段为 60 秒,提示客户端在 60 秒后再次尝试请求。

4. 504 Gateway Timeout

当服务器作为网关或代理时,未能及时从上游服务器收到响应,就会返回 504 Gateway Timeout 状态码。这可能是由于上游服务器响应时间过长或网络故障等原因导致的。例如,一个内容分发网络(CDN)作为代理服务器,从源服务器获取静态资源。如果源服务器响应缓慢,CDN 服务器在等待一定时间后仍未收到响应,就会返回 504 Gateway Timeout 状态码。客户端可以根据这个状态码,尝试重新发起请求或者联系网站管理员进行处理。

HTTP 状态码在不同角色中的实际应用

(一)前端开发

在前端开发中,HTTP 状态码是处理异步请求的重要依据。前端开发者通常会使用 AJAX(Asynchronous JavaScript and XML)或 Fetch API 来与服务器进行异步通信。通过检查响应的状态码,开发者可以根据不同的结果来更新页面内容或给用户提供相应的提示。

1. 成功响应处理

当请求返回 200 状态码时,开发者可以将服务器返回的数据渲染到页面上。例如,在一个新闻列表页面中,前端通过 AJAX 请求获取新闻数据,成功返回 200 状态码后,将新闻标题和摘要展示在页面上。开发者可以使用 JavaScript 动态地创建 HTML 元素,并将数据填充到这些元素中,然后将元素添加到页面的指定位置。

2. 错误响应处理
  • 当返回 404 状态码时,开发者可以显示一个提示信息,告知用户请求的资源不存在。比如,在一个图片展示页面中,如果请求的图片资源返回 404 状态码,页面可以显示一个默认的占位图片和提示文字,如 “图片未找到,请稍后重试”。
  • 当遇到 500 状态码时,开发者可以给用户显示一个友好的错误提示,如 “服务器暂时出现问题,请稍后再试”,同时记录错误信息,方便后续排查问题。可以使用浏览器的控制台或日志记录工具来记录请求的 URL、请求参数、响应状态码等信息。

(二)后端开发

后端开发者需要根据业务逻辑正确地返回合适的状态码。在设计 API 时,合理使用状态码可以让 API 的调用者更容易理解请求的处理结果,提高 API 的易用性和可维护性。

1. 业务逻辑处理与状态码返回
  • 在用户注册接口中,如果用户提交的表单数据不完整,服务器可以返回 400 Bad Request 状态码,并在响应中包含具体的错误信息,指导用户修正数据。例如,返回一个 JSON 格式的响应,包含错误字段和错误描述,如 { "error": "name field is required" }
  • 如果注册成功,则返回 201 Created 状态码,并返回新用户的相关信息,如用户 ID、用户名等。
  • 在处理用户权限验证时,如果用户没有权限访问某个资源,服务器返回 403 Forbidden 状态码,明确告知用户没有访问权限。
2. 异常处理与状态码

在后端代码中,需要对各种可能出现的异常进行捕获和处理,并返回相应的状态码。例如,在访问数据库时,如果出现数据库连接错误,服务器可以返回 500 Internal Server Error 状态码,并记录详细的错误日志,方便开发者进行调试。

(三)运维与监控

运维人员可以通过监控服务器返回的状态码来及时发现系统中的问题。状态码的变化可以反映出服务器的健康状况和业务的运行情况。

1. 实时监控与告警

使用监控工具对服务器的 HTTP 响应状态码进行实时监控。如果某个 API 频繁返回 500 状态码,就说明服务器可能存在内部错误,需要及时排查和修复。运维人员可以设置告警规则,当状态码出现异常时,及时通过邮件、短信或即时通讯工具通知相关人员。

2. 性能分析与优化

通过分析不同状态码的比例和趋势,运维人员可以评估服务器的性能和稳定性。例如,如果 404 状态码的比例过高,可能是网站的路由配置存在问题或资源链接失效,需要进行相应的调整。同时,对于 503 状态码频繁出现的情况,可以考虑对服务器进行扩容或优化性能,以提高服务器的处理能力。

总结

HTTP 状态码作为 Web 通信中的核心语言,为客户端和服务器之间的交互提供了清晰、准确的反馈机制。无论是前端开发、后端开发还是运维工作,深入理解和正确使用 HTTP 状态码都能够提高开发效率、增强系统的稳定性和用户体验。在实际工作中,我们应该根据具体的业务场景和需求