非常好的问题!但这根本不可能,除非您调用某种设置正确响应代码的脚本。
仅使用 nginx 且无 if 的可行解决方案
The try_files指示 http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files仅对最后一条语句执行内部重定向。但我们可以将它与index指示 http://nginx.org/en/docs/http/ngx_http_index_module.html#index并强制内部重定向。
# This will be the HTML file to display for the 503 error.
error_page 503 /maintenance/maintenance.html;
# Let nginx know that this particular file is only for internal redirects.
location = /maintenance/maintenance.html {
internal;
}
# Any request that starts with the maintenance folder is 503!
location ^~ /maintenance/ {
return 503;
}
# Instead of checking if a file exists and directly delivering it we check
# if a certain directory exists and trigger our index directive which will
# perform an internal redirect for us.
location / {
expires epoch;
try_files /maintenance/ $uri $uri/ /index.php?$args;
}
这种方法有什么缺点吗?
- 实际 301 重定向到目录,而不是停留在相同的 URL(搜索引擎)。
- 301 重定向的浏览器缓存可能是一个问题,这就是我添加
expires epoch
到位置块。
其他解决方案?
通过nginx配置文件
与其创建 HTML 文件,为什么不创建 nginx 配置文件并简单地重新加载进程呢?
nginx 配置可能如下所示(请注意,if
一点也不邪恶):
error_page 503 /maintenance.html;
location / {
include maintenance.conf;
if ($maintenance = 1) {
return 503;
}
try_files $uri $uri/ /index.php?$args;
}
内容maintenance.conf
file:
set $maintenance 0;
如果您想激活维护模式(在您的 shell 中):
echo set $maintenance 1;> maintenance.conf && service nginx reload
给shell朋友更进阶例如,您甚至可以用它扩展初始化脚本我的 LSB 兼容的 https://github.com/Fleshgrinder/nginx-sysvinit-script通过替换文件末尾的以下块:
*)
echo "Usage: ${NAME} {force-reload|reload|restart|start|status|stop}" >&2
exit 1
;;
使用以下块:
maintenance)
echo "set $maintenance 1;" > /etc/nginx/maintenance.conf && service nginx reload;
;;
production)
echo "set $maintenance 0;" > /etc/nginx/maintenance.conf && service nginx reload;
;;
*)
echo "Usage: ${NAME} {force-reload|reload|restart|start|status|stop|maintenance|production}" >&2
exit 1
;;
现在您只需执行以下命令(包括自动完成)即可进入维护模式:
service nginx maintenance
或者执行以下操作以恢复生产:
service nginx production
使用脚本/PHP 文件
另一种极其简单且神奇的方法是使用 PHP 文件来处理它。
location / {
try_files /maintenance.php $uri $uri/ /index.php?$args;
}
您的 PHP 文件看起来与您的 HTML 文件完全相同,您只需将以下内容添加到它的开头(假设 PHP 5.4+):
<?php http_response_code(503) ?><!doctype html>
<html>
<head>
<!-- ... more html ... -->