为什么无法下载状态码4XX和5XX的文件

时间:2019-02-10 14:56:27

标签: google-chrome http firefox curl wget

我注意到,许多Firefox和Chrome浏览器的http客户端都不允许下载4XX和5XX的HTTP响应代码的文件。但是,某些客户端允许进行这些下载,例如curl和wget(带有--content-on-error选项)。

Chrome和Firefox均未提供良好的异常消息。 Chrome失败,显示ERR_INVALID_RESPONSE。 Firefox失败,显示File not found。如上所述,对于同一网址的curl和wget而言。

我想知道在这种情况下是否有规范定义正确的行为?有充分的理由为什么Chrome和Firefox无法处理该请求?另外,他们没有提供适当的反馈似乎很奇怪。

我认为在大多数情况下,失败请求的下载是没有意义的,但是在某些情况下,这样做会有所帮助。一个很好的示例,即使在错误情况下,也可以下载文件,如果有一个客户端仅使用某种第三方格式与服务器通信。客户端将必须下载该请求的生成文件。如果发生错误,客户端应下载包含错误描述的文件。

例如RFC7231状态

  

使用错误状态码响应消息      通常包含表示错误情况的有效负载,例如      描述错误状态以及建议的下一步      解决它。


  

状态代码的4xx(客户端错误)类指示客户端      似乎犯了错误。除了回应HEAD要求外,      服务器应发送包含以下内容的解释的表示形式:      错误情况,以及它是临时的还是永久的      条件。这些状态代码适用于任何请求方法。      用户代理应该向用户显示任何包含的表示形式。

这不会在出现错误的情况下禁止下载。


根据第一个答案进行编辑:

我不认为此行为对用户友好,也不认为对用户友好确实是造成此问题的原因。例如,向用户显示错误代码和错误消息(在标题中提供)会更有意义。或至少用错误消息(例如“由于服务器响应错误而无法下载文件”)指示错误。可能有些服务器只能用XML或任何其他随机文件格式进行响应。

最让我感到烦恼的是,两种浏览器的响应均不同但任意,它们不会提示有关潜在问题的任何信息。

这可能是一个未记录的边缘情况,Chrome和Firefox都退回到了默认错误,但这似乎不太可能,尤其是因为这是一个边缘情况,在wget中带有特殊标志。

  

4XX:如果客户端做错了事,为什么还要假设要下载文件?

如果我们假设API的端点使用某种文件格式进行响应,则可以合理地假设以该格式提供了错误消息,其中包括客户端做错了什么的提示。因此该文件可以帮助修复客户端错误。

5 个答案:

答案 0 :(得分:3)

我不知道该主题的任何规范。 该行为应尽可能对用户友好。

4XX: 如果客户端做错了什么,为什么还要假设文件下载?此外,在错误使用(例如无效的URL)和处理文件下载的情况下,客户端软件也不会有所不同。

5xx: 如您所说,大多数api提供错误信息,但是您也不能区分下载的情况,例如提供文件的内部错误。

您可以如上所述使用wget和curl进行这种行为,但是对于以编程方式使用此类API而言,它既不友好也不实用。

记住上面的信息,Chrome和firefox只是试图变得用户友好。

我希望我能以某种方式回答您的问题或挑战其背后的想法。 :)

答案 1 :(得分:1)

chromium handle download and not 2xx,我们看到:

  // The response code indicates that this is an error page, but we don't
  // know how to display the content.  We follow Firefox here and show our
  // own error page instead of intercepting the request as a stream or a
  // download.

因此Chrome浏览器遵循Firefox,并且两者都与RFC完全一致,浏览器知道与错误情况相关的this payload is unidentified数据,因此不能将其保存为相关文件。由于正在下载它,所以大概浏览器无法显示有效负载,但是无论哪种情况都已指示不要这样做,因此在错误上下文中显示它不是一个安全的选择。由于这是一个错误,因此发送者很有可能将部分响应与错误代码组合在一起,这意味着有效负载内容可能是来自2xx响应/等的数据的不完整或损坏的表示形式。

如果回顾一下wget,--content-on-error是一个特定的选项,因为对于一般的浏览器来说,这样做是错误的。使用有效负载类型的客户端可以在与服务器直接交互时检查错误,而wget仅提供选项来帮助您调试这种交互。普通浏览器比文本CLI具有更少的功能来帮助模仿其他客户端进行调试,因为文本CLI主要是在调试时模仿其他客户端。

答案 2 :(得分:1)

  

我想知道是否有定义正确的规范   在这种情况下的行为?是否有充分的理由为什么不能提出要求   由Chrome和Firefox处理?而且,他们似乎很奇怪   没有提供适当的反馈。

没有这样的规范,但是铬项目成员认为这是一个琐碎的问题,不太可能在不久的将来解决。建议不要通过发送适当的HTTP状态将其固定在服务器上。

  

Chromium项目成员的回复:此问题已存在一年以上。如果不再存在   重要或似乎不太可能解决,请考虑将其关闭   退出。如果重要,请重试该问题。

     

不便之处,敬请原谅。   可用

enter image description here

您可以在此处查看更多详细信息 Issue 479265

地下发生了什么?

我进一步检查了chromium的源代码以查找实际情况,发现对于任何非200的下载状态,它们只是抛出ERR_INVALID_RESPONSE(无效的服务器响应)错误。

enter image description here

长话短说,您必须忍受浏览器的这种行为,它不会得到改善。

答案 3 :(得分:0)

@lossleader's answer的基础上,似乎Chromium决定遵循Firefox的决定,如果响应失败,则不下载文件。

此问题似乎有历史。在2005年,AOL网站出现了一个问题,该问题返回了状态代码500,并导致用户下载了.exe文件。有一个“修复程序”仅返回404来响应触发下载并带有错误响应的响应。可以找到相应的问题here

从2008年开始有一个未解决的问题,抱怨此错误并指出它会引起误解。可以找到相应的问题here

我在Super User上找到了更详细的答案。

我仍然认为,至少为用户提供选择下载文件还是至少显示一个更有意义的错误页面是正确的。另一方面,在大多数情况下,无意下载响应代码!= 2XX并提示服务器错误。因此,似乎此问题对浏览器供应商而言优先级较低,并且似乎“不值得麻烦”。

答案 4 :(得分:-1)

这些答案似乎都绕过了这里的基本原理:您试图对代码中的错误给出特定于浏览器的解释。在我看来,在所有相关情况下,您的代码都会以某种方式失败而没有错误处理。

4xx错误?根据您确定的规则,您已经向服务器发送了错误的请求。从技术上讲,这不是浏览器的错。

5xx错误? 您的服务器崩溃了,并没有引发任何错误。在某些类型的服务器上(Django),500错误将是一堆调试信息,您可能不应该向用户显示该信息。

因此,从架构的角度来看,您要的是奇怪的;您想通过修改浏览器的响应而不是固定代码以适当地响应来掩盖事实,那就是搞砸了。