chaihongjun.me

nginx制作503自定义维护页面并设定Retry-After响应头

马上要到每年一度的3.15消费者权益保护日了,作为商家这段时间都是非常敏感而小心的。无论是线上还是线下的广告宣传这个时候都特别注意宣传品的内容,特别怕触犯了什么规则。维护的网站也面临了一个需要在不关闭网站的前提下,针对一个涉嫌敏感内容的页面的内容做一些研判或修改。我们的需求是当用户访问我们的网站的时候,给用户显示一个网站正在维护的通知。于是在服务器端的nginx可以这样的配置:

set $flag 0; 
if ($request_uri !~ "(/houtai/).*$"){
      set $flag "${flag}1";
 }
if ($request_uri !~ "/503/503.html$" ){
      set $flag "${flag}2";
 }
if ($request_uri !~ "(/503/css/.*)$" ){
      set $flag "${flag}3";
 }
if ($request_uri !~ "(/503/images/.*)$" ){
      set $flag "${flag}4";
}

if (-f $document_root/503/503.html) {
      set $flag "${flag}5";
}

    error_page 503 @maintenance;
       location @maintenance {
         rewrite ^(.*)$ /503/503.html break;
  }
  
  location / {  
       if ( $flag = "012345") {
            return 503;
         }
  }

503这个目录里面放了显示网站正在维护的页面的文件,本身是需要排除的不然503这个页面就无法正常显示了,houtai那个目录是需要排除在外。

根据上面的代码可以再次精简:

set $flag 0; 
if ($request_uri !~ "/houtai"){
      set $flag "${flag}1";
 }
if ($request_uri !~ "/503" ){
      set $flag "${flag}2";
 }

    error_page 503 @maintenance;
       location @maintenance {
         rewrite ^(.*)$ /503/503.html break;
  }
  
  location / {  
       if ( $flag = "012") {
            return 503;
         }
  }

当然,在MDN上面介绍了除了设置好一个用户友好的503页面之外:

与之同时,在可行的情况下,应该在 Retry-After 首部字段中包含服务恢复的预期时间。

所以这个Retry-After是个什么东西?MDN也同样有介绍:

在HTTP协议中,响应首部 Retry-After 表示用户代理需要等待多长时间之后才能继续发送请求。这个首部主要应用于以下两种场景:

当与 503 (Service Unavailable,当前服务不存在) 响应一起发送的时候,表示服务下线的预期时长。

当与重定向响应一起发送的时候,比如 301 (Moved Permanently,永久迁移),表示用户代理在发送重定向请求之前需要等待的最短时间。

这里我们503正好可以用,语法规则:

Retry-After: <http-date>
Retry-After: <delay-seconds>

MDN给的例子也有两种:

Retry-After: Wed, 21 Oct 2015 07:28:00 GMT
Retry-After: 120

第一种的时间格式的意思是在那个具体的时间之后重新尝试。第二个则是表示需要等待多少秒之后才可以重试。

这里为了简便起见想在24小时候之后恢复正常返回码200,于是设置:

Retry-After:86400

那么在nginx上应该怎么设置呢?应该是用到add_header指令。再参考SF上面的方法:

1.7.5 and later, append the always parameter to the add_header directive.

实际的方式:

add_header Retry-After 86400 always;

然后,通过curl或者访问网站。可以看到:


知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»