Learn HTTP 1.1 Status Code Part.4

Learn HTTP 1.1 Status Code Part.4

by xujiwei(http://www.xujiwei.com/)

前一篇介绍了 4xx 系列状态码 中 400 到 405,这篇接着讲剩下的 4xx 系列。

6.7. 406 Not Acceptable

客 户端在收到 406 Not Acceptable 状态码时,一般是因为服务器在处理客户端请求时,找不到对应客户端发送过来的请求头部 的 Accept 字段中列举的响应类型的响应内容,例如使用 Ajax 时,如果通信数据格式选择 json,发送请求时头部 Accept 字段一般 会设置为 application/json,但是如果服务端并不支持 json,那么服务端可以发送一个 406 Not Acceptable,同时 也应该在 Content-Type 字段中指定客户端所请求的资源的格式,这时客户端可以考虑使用另外的格式来接收响应。

不过备注中说 到,如果没有合适的资源来响应客户端的请求,HTTP 1.1 服务器也可以发送一个响应。当然发送 406 Not Accepteble 是一个更好 的选择,这样客户端就能知道什么格式的数据才能是服务器所能接受的。

6.8. 407 Proxy Authentication Required

通 常情况下,这个状态码应该是代理服务器发过来的,表示客户端首先应该进行代理服务器的认证才能继续完成请求,在 IE 里可能会表现为提示用户输入代理服 务器的用户名和密码,如果选择取消则会提示“您必须通过代理的身份验证,然后 Web 服务器才能处理您的请求。”。

6.9. 408 Request Timeout

请 求超时,出现这个状态码时,有可能是服务端的问题,也有可能是客户端的问题(呃,有点废话……)。但是,可能在一些 Web 服务器中,并不会在运行超时 时返回 408 Request Timeout。例如在 ASP 中,如果运行一个超长时间的脚本,IIS 并不会发 送 408 Request Timeout 状态码,而是发送一个 500 Internal Server Error,所以如果在写一个程序时,如 果运行时间已经超过了预期,那么可以自己结束程序运行并向客户端发送一个 408 Request Timeout。

在 HTTP 1.1 状 态码的定义中,如果客户端收到一个 408 Request Timeout 状态码,可以在过一段时间后重新发送这个请求。因此,如果是因为客户端的原 因导致的脚本超时,例如客户端网络速度太慢等,推荐发送一个 408 Request Timeout 状态码,但是如果是由服务器的原因,例如不能处理 过大的文件,则应该直接给出错误,而不是发送一个 408 Request Timeout。

6.10. 409 Conflict

409 Conflict 表 示服务器在处理客户端发送的请求时发生了冲突,和 403 Forbidden、404 Not Found 等一样,服务器应该同时也给出出问题的原因 或解决方法。

很可能发生 409 Conflict 错误的时候是使用 PUT 方法发送请求时,如果所请求的资源已经被第三方修改过,这 时就需要解决两次修改之间的冲突问题。

这个状态码可以与 SVN 中的冲突一起理解,在 SVN 中,如果你修改一个文件的工作副本,在提 交之前又有另外一个人修改并提交了同一个文件的副本,这时就需要解决两个版本之间的冲突,例如合并两个版本之间的不同之处等。

6.11. 410 Gone

如 果客户端请求的资源已经永久删除了,并且不知道有什么其他的资源可以代替它,那么服务器就会发送一个 410 Gone 状态码,指示这个资源已经永久删 除了。如果需要的话,客户端可以在经过用户确认后删除这个资源的链接。如果服务器不能确定客户端所请求的资源是永久的被删除了还是由于某种原因临时不可用 了,那么 404 Not Found 是一个更好的状态码。

一般情况下,410 Gone 可以用于服务器上一些临时的资源,或者不再提 供的某些资源。例如一些不用存档的通知信息等。

与 404 Not Found,这个状态码显示更绝情一些,出 现 404 Not Found 时,服务器的意思是过一段时间之后这个资源有可能还会再可用,但是如果收到了 410 Gone,那么很明显的通知了客 户端“你走吧,这个资源已经不在了,而且也找不到它新的地址了”。那么,如果不是那么确定的时候,还是用 404 Not Found 吧,以后还有“挽 回”的可能。

6.12. 411 Length Required

客户端发送请求时,如 果是使用的 POST 或 PUT 方法,一般都应该加送一个 Content-Length 头,用来指明所发送请求实体的大小,这样服务器在处理请求 时可以提取出整个请求的数据。

如果客户端在发送请求时从服务端收到了一个 411 Length Required 状态码,那么应该在原 来请求的基础上添加一个正确可用的 Content-Length 头部字段再重新发送。

6.13. 412 Precondition Failed

预 处理失败,这通常在客户端发送来的请求中包含了服务端不允许的头部字段或头部字段中的值或其格式不正确,这样可以防止客户端发送一些非法头部信息。

我 对这个状态码的定义并不是很懂,如果理解有错希望指正,原文定义在这里

6.14. 413 Request Entity Too Large

客 户端在收到 413 Request Entity Too Large 状态码时应该意识到它所发送的请求是否过大了。例如在上传文件时,如果选择了一 个过大的文件,那么服务器在没有接收完所有数据时就可能会发送一个 413 Request Entity Too Large 状态码,这时客户端应该 提示用户文件过大并重新选择一个文件等,同时服务器可能会关闭连接以免继续传输请求浪费带宽。

如果出现请求实体过大并不是因为服务器不能处 理过大的文件,而是由于一些临时的原因导致了服务器暂时不能客户端的请求,那么服务器可以在发 送 413 Request Entitiy Too Large 状态码后再头部添加一个 Retry-After 字段,表示客户端可以在此时间之后 重新尝试发送请求。

6.15. 414 Request-URI Too Long

在 HTTP/1.1 Section 3.2.1推荐的 URI 长度应该控制在 255 字节以内,因为一些比较 老的客户端不支持大于 255 字节的 URI。虽然这个限制在现在已经有些过时了,不过浏览器对 URI 的长度也还是有限制的,例如 在 IE 中 URI 的最大长度在 2083 个字节。测试中发现服务器对于 URI 的长度也是有限制的,这也就是 414 Request- URI Too Long 存在的意义了。在服务器觉得客户端所发送的 URI 过长时,就可以返回一个 414 Request- URI Too Long 状态码向客户端说明发生了什么错误。

通常这个情况会发生在客户端使用了 GET 方法去发送本应使 用 POST 方法发送的数据,例如将一个表单使用 GET 方法发送,那么表单中的所有字段会以查询字符器的方式附加到 URI 的最后,这时很有可 能 URI 的长度就会超过了服务器的限制,从而使服务器发送了了 414 Request-URI Too Long 状态码。

还有一种 情况就是用户刻意去构造一个超长的 URI 来攻击服务器了,这个内容不是本篇的范围,就不深入了,我暂时也没能力去讲有关缓冲区溢出之类的内容:)

6.16. 415 Unsupported Media Type

客 户端在发送请求时,一般都需要在头部中添加一下 Content-Type 字段,用于指明所发送请求的内容的类型,例如使用 POST 方法发送表单 时 Content-Type 字段的值就为 application/x-www-form-urlencoded。因此,客户端如果收到 了 415 Unsupported Media Type 状态码,也就意味着它发送的请求的格式不被服务器接受,像在 XML-RPC 的调用过程 中,通信体格式应该为 application/xml 或 text/xml,服务端如果严格检查的话,应该在请求格式不为 application /xml 或 text/xml 时给出一个 415 Unsupported Media Type 的状态码,当然这个检查并不是必须的,XML 也 是文本内容,text/plain 的类型应该也是可接受的。

6.17. 416 Requested Range Not Satisfiable

在 多线程下载中,下载工具是通过在请求头部中添加 Range 字段来指定客户端所需要的资源的内容范围,服务器通过识别这个 Range 字段,定位到资 源的指定位置,并发送指定范围内的内容。如果客户端请求头部中的 Range 字段的起始值超过了它所请求资源的大小并且请求头部没有 If- Range 字段,那么服务器就会返回 416 Request Range Not Satisfiable,这时客户端最好应该删除已经下载的数据并 重新发送一个不带 Range 字段的请求以确定资源的真实大小。

如果是使用字节确定范围的话,那么服务器在返 回 416 Request Range Not Satisfiable 状态码的同时,也应该添加一个 Content-Range 字段,用于指定 客户端所请求的资源的实际大小,这样客户端在收到响应时可以根据请求资源的实际大小重新发送一个请求。

6.18. 417 Expectation Failed

客 户端发送的请求中如果有 Except 字段,但是服务器无法满足的话,那么就可以返回一个 417 Expectation Failed 状态码。

这 个状态码一个常见的用途就是客户端的请求带了一个 Except: 100-continue 字段,但是代理服务器或者 Web 服务器不能处理这个处 理 100 Continue,所以服务器返回 417 Expectation Failded 状态码。

这个状态码 与 100 Continue 以及请求头部 Except 字段之间的关系以及使用可以参考 HTTP/1.1: Connection, Section 8.2.3 Use of the 100 (Continue) Status

后 记

上个星期是学期最后一周,一堆考查课作业要交,晕得一塌糊涂……

未完待续。

参 考资料

1. HTTP/1.1 Protocol Section 3.2.1 General Syntax

2. What is the maximum length of a URL?

3. What is the limit on QueryString / GET / URL parameters?

4. HTTP/1.1: Header Field Definitions

5. HTTP/1.1: Connectinos

系列目录

1. Learn HTTP 1.1 Status Code Part.1 : Successful 2xx

2. Learn HTTP 1.1 Status Code Part.2 : Redirection 3xx

3. Learn HTTP 1.1 Status Code Part.3 : Client Error 400-405

发表评论?

0 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>