2月阅读周·HTTP权威指南:HTTP报文之状态码篇

举报
叶一一 发表于 2025/02/28 16:50:31 2025/02/28
51 0 1
【摘要】 引言HTTP(Hypertext Transfer Protocol,超文本传输协议[插图])是在万维网上进行通信时所使用的协议方案。HTTP有很多应用,但最著名的是用于Web浏览器和Web服务器之间的双工通信。《HTTP权威指南》一书将HTTP中一些互相关联且常被误解的规则梳理清楚,并编写了一系列基于各种主题的章节介绍HTTP各方面的特性。纵观全书,对HTTP“为什么”这样做进行了详细的解...

引言

HTTP(Hypertext Transfer Protocol,超文本传输协议[插图])是在万维网上进行通信时所使用的协议方案。HTTP有很多应用,但最著名的是用于Web浏览器和Web服务器之间的双工通信。

《HTTP权威指南》一书将HTTP中一些互相关联且常被误解的规则梳理清楚,并编写了一系列基于各种主题的章节介绍HTTP各方面的特性。纵观全书,对HTTP“为什么”这样做进行了详细的解释,而不仅仅停留在它是“怎么做”的。此外,这本书还介绍了很多HTTP应用程序正常工作所必需且重要的非HTTP技术。

这本书主要包括以下内容:

  • 第一部分描述了Web的基础构件与HTTP的核心技术
  • 第二部分重点介绍了Web系统的结构构造块:HTTP服务器、代理、缓存、网关以及机器人应用程序。
  • 第三部分提供了一套用于追踪身份、增强安全性以及控制内容访问的技术和技巧。
  • 第四部分涵盖HTTP报文主体和Web标准,前者包含实际内容,后者描述并处理主体内容。
  • 第五部分介绍了发布和传播Web内容的技巧。
  • 第六部分是一些很有用的参考附录,以及相关技术的教程。

HTTP报文

如果说HTTP是因特网的信使,那么HTTP报文就是它用来搬东西的包裹了。

状态码

状态码为客户端提供了一种理解事务处理结果的便捷方式。

100~199——信息性状态码

HTTP/1.1向协议中引入了信息性状态码。这些状态码相对较新,关于其复杂性和感知价值存在一些争论,而受到限制。

表1-1列出了已定义的信息性状态码。

1-1.jpg

100 Continue状态码尤其让人糊涂。它的目的是对这样的情况进行优化:HTTP客户端应用程序有一个实体的主体部分要发送给服务器,但希望在发送之前查看一下服务器是否会接受这个实体。这可能会给HTTP程序员带来一些困扰,因此在这里进行了比较详细(它如何与客户端、服务器和代理进行通信)的讨论。

1、客户端与100 Continue

如果客户端在向服务器发送一个实体,并且愿意在发送实体之前等待100 Continue响应,那么,客户端就要发送一个携带了值为100 Continue的Expect请求首部(参见附录C)。如果客户端没有发送实体,就不应该发送100 Continue Expect首部,因为这样会使服务器误以为客户端要发送一个实体。

从很多方面来看,100 Continue都是一种优化。客户端应用程序只有在避免向服务器发送一个服务器无法处理或使用的大实体时,才应该使用100 Continue。

由于起初对100 Continue状态存在一些困惑(而且以前有些实现在这里出过问题),因此发送了值为100 Continue的Expect首部的客户端不应该永远在那儿等待服务器发送100 Continue响应。超时一定时间之后,客户端应该直接将实体发送出去。实际上,客户端程序的实现者也应该做好应对非预期100 Continue响应的准备(这很烦人,但确实如此)。有些出错的HTTP应用程序会不合时宜地发送这个状态码。

2、服务器与100 Continue

如果服务器收到了一条带有值为100 Continue的Expect首部的请求,它会用100Continue响应或一条错误码来进行响应(参见表3-9)。服务器永远也不应该向没有发送100 Continue期望的客户端发送100 Continue状态码。但如前所述,有些出错的服务器可能会这么做。

如果出于某种原因,服务器在有机会发送100 Continue响应之前就收到了部分(或全部)的实体,就说明客户端已经决定继续发送数据了,这样,服务器就不需要发送这个状态码了。但服务器读完请求之后,还是应该为请求发送一个最终状态码(它可以跳过100 Continue状态)。

最后,如果服务器收到了带有100 Continue期望的请求,而且它决定在读取实体的主体部分之前(比如,因为出错而)结束请求,就不应该仅仅是发送一条响应并关闭连接,因为这样会妨碍客户端接收响应。

3、代理与100 Continue

如果代理从客户端收到了一条带有100 Continue期望的请求,它需要做几件事情。如果代理知道下一跳服务器(在第6章中讨论)是HTTP/1.1兼容的,或者并不知道下一跳服务器与哪个版本兼容,它都应该将Expect首部放在请求中向下转发。如果它知道下一跳服务器只能与HTTP/1.1之前的版本兼容,就应该以417 Expectation Failed错误进行响应。

如果代理决定代表与HTTP/1.0或之前版本兼容的客户端,在其请求中放入Expect首部和100 Continue值,那么,(如果它从服务器收到了100 Continue响应)它就不应该将100 Continue响应转发给客户端,因为客户端可能不知道该拿它怎么办。

代理维护一些有关下一跳服务器及其所支持的HTTP版本的状态信息(至少要维护那些最近收到过请求的服务器的相关状态)是有好处的,这样它们就可以更好地处理收到的那些带有100 Continue期望的请求了。

200~299——成功状态码

客户端发起请求时,这些请求通常都是成功的。服务器有一组用来表示成功的状态码,分别对应于不同类型的请求。表1-2列出了已定义的成功状态码。

1-2.jpg

300~399——重定向状态码

重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个替代的响应而不是资源的内容。如果资源已被移动,可发送一个重定向状态码和一个可选的Location首部来告知客户端资源已被移走,以及现在可以在哪里找到它。这样,浏览器就可以在不打扰使用者的情况下,透明地转入新的位置了。

可以通过某些重定向状态码对资源的应用程序本地副本与源端服务器上的资源进行验证。比如,HTTP应用程序可以查看其资源的本地副本是否仍然是最新的,或者在源端服务器上资源是否被修改过。客户端发送了一个特殊的If-Modified-Since首部,说明只读取1997年10月之后修改过的文档。这个日期之后,此文档并未被修改过,因此,服务器回送了一个304状态码,而不是文档的内容。

总之,在对那些包含了重定向状态码的非HEAD请求进行响应时,最好要包含一个实体,并在实体中包含描述信息和指向(多个)重定向URL的链接——参见图3-14的第一个响应报文。表3-8列出了已定义的重定向状态码。

大部分差别都源于HTTP/1.0和HTTP/1.1应用程序对这些状态码处理方式的不同。当HTTP/1.0客户端发起一个POST请求,并在响应中收到302重定向状态码时,它会接受Location首部的重定向URL,并向那个URL发起一个GET请求(而不会像原始请求中那样发起POST请求)。

HTTP/1.0服务器希望HTTP/1.0客户端这么做——如果HTTP/1.0服务器收到来自HTTP/1.0客户端的POST请求之后发送了302状态码,服务器就期望客户端能够接受重定向URL,并向重定向的URL发送一个GET请求。

问题出在HTTP/1.1。HTTP/1.1规范使用303状态码来实现同样的行为(服务器发送303状态码来重定向客户端的POST请求,在它后面跟上一个GET请求)。

为了避开这个问题,HTTP/1.1规范指出,对于HTTP/1.1客户端,用307状态码取代302状态码来进行临时重定向。这样服务器就可以将302状态码保留起来,为HTTP/1.0客户端使用了。

这样一来,服务器要选择适当的重定向状态码放入重定向响应中发送,就需要查看客户端的HTTP版本了。

400~499——客户端错误状态码

有时客户端会发送一些服务器无法处理的东西,比如格式错误的请求报文,或者最常见的是,请求一个不存在的URL。

浏览网页时,我们都看到过臭名昭著的404 Not Found错误码——这只是服务器在告诉我们,它对我们请求的资源一无所知。

很多客户端错误都是由浏览器来处理的,甚至不会打扰到你。只有少量错误,比如404,还是会穿过浏览器来到用户面前。表1-3显示了各种客户端的错误状态码。

1-3.jpg

500~599——服务器错误状态码

有时客户端发送了一条有效请求,服务器自身却出错了。这可能是客户端碰上了服务器的缺陷,或者服务器上的子元素,比如某个网关资源,出了错。

代理尝试着代表客户端与服务器进行交流时,经常会出现问题。代理会发布5XX服务器错误状态码来描述所遇到的问题。表1-4列出了已定义的服务器错误状态码。

1-4.jpg

总结

状态码为客户端提供了一种理解事务处理结果的便捷方式。


作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。