在HTTP响应标头之后重试 - 它会影响任何事情吗?

时间:2010-09-21 20:10:14

标签: http http-headers

如果由于临时过载而我想礼貌地拒绝网站上的服务,HTTP响应503 Service Unavailable似乎是合适的。该规范提到使用503发送Retry-after标题。

有什么意义吗? Retry-after会影响任何事情吗?浏览器是否会关注它?

4 个答案:

答案 0 :(得分:76)

Retry-After 标题

的当前状态

自最初发布此问题以来,客户端和服务器中 Retry-After 标头的实施在最近几年发生了一些变化。所以我想我会提供更新的答案。

首先,RFC 2616,section 14.37 Retry-After声明:

  

Retry-After响应标头字段可与503(服务不可用)响应一起使用,以指示服务预计对请求客户端不可用的时间。

     

...

     

其使用的两个例子是

  Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
  Retry-After: 120
     

在后一个例子中,延迟是2分钟。

支持客户端和服务器软件

以下是各种软件中 Retry-After 标头的代码库提交消息,公告和文档。

铬/铬

2012年11月22日的代码提交,其中包含日志消息: Added detection timeouts and usage of Retry-After HTTP header

的Mozilla /火狐

2012年3月27日的代码提交,其中包含log messeage:Implement Handling of 5xxs, X-Weave-Backoff, Retry-After。此外,Mercurial存储库中有three other mentions of Retry-After header

最初在2004年1月6日提交了一个错误,标题为Retry-After sent with HTTP 503 response is ignored

Googlebot的

关于处理网站停机时间的Google网站管理员中心博客文章提到了Retry-After header may be used to determine when to recrawl the URL

Bingbot / MSNBot会

找不到任何正式的Retry-After支持文档。但是,随机论坛中有一些提及在503响应中使用此标题来限制微软的机器人。

Nginx的

add_header directive州:

  

如果响应代码等于200,201,204,206,301,302,303,304或307,则将指定字段添加到响应头。

因此,使用version:

为503响应添加Retry-After标头
  • 1.7.4及更早版本,使用第三方模块,例如Headers More

  • 1.7.5及更高版本,将always参数附加到add_header指令。

的Apache

与Nginx不同,Apache header documentation没有表明它不能在503响应上发送Retry-After标头。然而,关于非2xx响应,文档声明:

  

向本地生成的非成功(非2xx)响应添加标头,例如重定向,在这种情况下,只有与always相对应的表在最终响应中使用。

这是一个SO answer,根据文档的建议,为503响应设置了一个带有始终条件的Retry-After标头。

AskApache文章提供了有关如何instruct search engines to come back使用带有Retry-After标头的503响应的其他配置示例。

客户端测试

我写了一个Ruby服务器,它只返回一个503响应,Retry-After标头设置为10秒,一个包含随机数的主体。

require 'sinatra'

get '/' do
  headers 'Content-Type' => 'text/plain', 'Retry-After' => '10'
  status 503
  body rand(1000).to_s
end

我访问了它:

  • OpenBSD 5.8使用Chromium 44,Firefox-ESR 38和Seamonkey 2.33,
  • Mac OSX 10.7.5使用Chrome 47和Safari 6.1,
  • 使用Chrome 48,Firefox 41和Edge 25的Windows 10。

我希望这些浏览器在10秒后自动刷新URL并显示一个新的随机数。但是,即使几分钟后,所有浏览器都没有重试。我尝试了更短和更长的Retry-After时段以及相同的结果。服务器访问日志确认没有从任何这些浏览器重试。

另外,"软"在Retry-After期间刷新之前立即重新获取URL。因此,Retry-After标头不能用于限制"刷新快乐"用户。我之所以提到这一点是因为我在一些论坛中看到这个标题可以用来阻止不耐烦的用户锤击你的网站。

作为旁注,对于"软"而言似乎合乎逻辑。刷新以在超时期限之前没有动作,但是"硬"或缓存旁路刷新将忽略任何超时并立即重新获取URL。

结论

对客户端和服务器上的 Retry-After 标头的支持似乎仍然有点粗略。尽管如此,如果配置不困难,最好为503个响应设置重试超时。

即使Googlebot是唯一支持标头并在超时期限后实际重试的客户端,它也可能会使您的网页无法取消索引 - 而不是404,500,502或504响应。

答案 1 :(得分:21)

据我所知,没有浏览器会关注Retry-after标题。代理和缓存可能,但

显然,有些浏览器现在对Retry-After提供了一定程度的支持(尽管支持仍然是最好的)。我并不完全相信在浏览器中这样做的好处;通常,缓存失败被认为是个坏主意。但如果您知道何时再次接受请求,告诉客户不会受到伤害。 (如果你比预期更早回来,那么任何真正尊重标题的程序都应该假设 - 并报告 - 该网站仍在关闭。)

最明显的好处是,Googlebot(以及可能的其他蜘蛛)似乎会关注标题,如果它存在,可以防止它在一段时间内对页面进行非索引编制。

尽管如此......如果添加起来很简单,并且您可以对服务何时可用提出合理准确的估计,那就去吧。不过,我不建议你不要这样做。无论如何它只是建议,并且在那里错误的时间可能导致更多的问题,而不是包括标题。

答案 2 :(得分:8)

我认为这是一个鸡与蛋的问题:没有浏览器目前正在实施Retry-after,因为没有任何网站都会这么做。在我看来,继续将其作为服务发送给用户。如果他们选择的Web浏览器没有实现它,那就是他们的浏览器只是没有给他们提供有用的信息。你做到了!

在寻求实现具有多个竞争实现的标准时,我总是尽量遵守标准而不关注不同的实现(除非我特意尝试模拟实现,例如cURLing但是将我的标头伪装成看起来像一个Web浏览器)。否则,我们最终会遇到事实上的标准,如果你还记得你不想要的IE-dominence日子那么!

答案 3 :(得分:3)

如果您想在X时间之后发送自动刷新,则可以发送

Refresh: 120; url=http://your_url.com
PHP中的

header("Refresh: "    .$retry_time."; url=". $url);

要刷新当前页面,您可以使用$_SERVER["REQUEST_URI"]获取$ url。

我在不同版本的Opera,Firefox和Internet Explorer中成功测试了此标题。

此标题甚至可用于刷新图像等二进制内容(但仅限于直接加载或在框架中加载的内容 - IMG-Tag不会重新加载)。