本文介绍了nginx;如果仅使用try_files存在文件,则返回响应代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 IfIsEvil 我一直在尝试仅使用指令try_files来设置配置这样一来,对于任何URI,如果没有维护文件,则维护页面将与响应代码503一起显示,无一例外,即包括php页面.

Since IfIsEvil I've been trying to set up a configuration using the directive try_files only so that a maintenance page is displayed together with the response code 503, for any URI without exception, i.e. including php pages, if a maintenance file exist.

我的配置有两个问题:

  1. 维护页面不显示php URI.
  2. 如果存在maintenance.html文件,则不会返回响应代码503.

我见过类似的问题 [1] [2] ,但没有一个仅使用try_files的解决方案(与使用if指令相对)如果存在相应的文件,则显示带有响应代码503的维护页面.这样的解决方案有可能吗?

I've seen similar questions [1],[2] but none with a solution that uses try_files only (as opposed the using the if directive) and that unconditionally serves a maintenance page with the response code 503, if the corresponding file is present. Is such a solution possible?

以下是我当前无法正常使用的conf文件.它不包含503响应代码设置,因为我不知道要使其如上所述地工作应该去哪里.

Below is my current non-working conf file. It doesn't contain a 503 response code setting because I don't understand where it's supposed to go in order for it to work as described above.

worker_processes            1;

error_log                   /var/log/nginx/error.log debug;

events {
    worker_connections      1024;
}

http {
    include                 mime.types;
    default_type            application/octet-stream;

    index                   index.php index.html index.htm;

    server {
        listen                  80;
        server_name             rpi;
        root                    /www;

        location / {
            try_files           /maintenance.html $uri $uri/ /index.php?$args;

            # pass the PHP scripts to FastCGI server
            location ~ \.php$ {
                try_files           $uri =404;
                fastcgi_pass        unix:/run/php-fpm/php-fpm.sock;
                fastcgi_index       index.php;
                include             fastcgi.conf;
            }
        }
    }
}

我想我的问题也可以这样表达:是否可以使try_files用作if控件结构?如果不是它本身,是否可以将上述目标与if指令以外的其他指令组合以达到上述目的?

I guess that my question could alternatively be phrased like this: Can try_files be made to work as an if control structure? If not by itself, can it, with the above goal, be combined with other directives to act as such, excluding the if directive?

编辑:以下是我正在使用的使用if的解决方案,方法是将其包含在服务器部分:

edit: Below is a solution using if that I'm currently using by including it in the server section:

error_page              503 @maintenance;

if (-f $document_root/maintenance.html) {
        return          503;
}

location @maintenance {
        try_files       /maintenance.html =404;
}

推荐答案

很好的问题!除非您调用某种设置正确响应代码的脚本,否则根本不可能.

Very good question! But it's not possible at all unless you call some kind of script that sets the correct response code.

try_files指令仅执行内部重定向对于最后的陈述.但是我们可以将其与 index指令结合使用,并强制内部重定向.

The try_files directive is only performing an internal redirect for the last statement. But we can combine it with the index directive and force an internal redirect.

# 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的原因.
  • Any drawbacks with this method?

    • Actual 301 redirect to the directory instead of staying at the same URL (search engines).
    • Browser caching of 301 redirects might be an issue, that's why I added the expires epoch to the location block.
    • 为什么不创建nginx配置文件并简单地重新加载过程,而不是创建HTML文件?

      Instead of creating an HTML file, why not create an nginx configuration file and simply reload the process?

      • 更好的表现!
      • 更容易理解!
      • 没有副作用!

      nginx的配置可能如下所示(请注意,此if根本不是邪恶的):

      The nginx configuration could look like the following (note that this if isn't evil at all):

      error_page 503 /maintenance.html;
      
      location / {
        include maintenance.conf;
        if ($maintenance = 1) {
          return 503;
        }
        try_files $uri $uri/ /index.php?$args;
      }
      

      maintenance.conf文件的内容:

      set $maintenance 0;
      

      如果要激活维护模式(在您的外壳中):

      And if you want to activate the maintenance mode (in your shell):

      echo set $maintenance 1;> maintenance.conf && service nginx reload
      

      面向Shell朋友的更高级您甚至可以用此扩展初始化脚本,例如通过替换我的符合LSB的脚本文件末尾的以下代码段:

      More advanced for shell friendsYou could even extend an init script with this, for instance my LSB compliant one by replacing the following block at the end of the file:

      *)
        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
      ;;
      

      现在您只需执行以下命令(包括自动完成)即可进入维护模式:

      And now you can simply execute the following command (including auto-completion) to go into maintenance mode:

      service nginx maintenance
      

      或以下内容重新投入生产:

      Or the following to go back into production:

      service nginx production
      

      带有脚本/PHP文件

      另一种非常简单的方法就像魅力一样工作,那就是使用处理它的PHP文件.

      With a script / PHP file

      Another extremely easy approach that would work like a charm is to use a PHP file that handles it.

      location / {
          try_files /maintenance.php $uri $uri/ /index.php?$args;
      }
      

      您的PHP文件看上去与您的HTML文件完全一样,只需在开头添加以下内容(假设PHP 5.4 +):

      Your PHP file would look exactly like your HTML file, you only have to add the following to it's beginning (assuming PHP 5.4+):

      <?php http_response_code(503) ?><!doctype html>
      <html>
      <head>
      <!-- ... more html ... -->
      

      这篇关于nginx;如果仅使用try_files存在文件,则返回响应代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 06:08