6

PHP-FastCGIを使用してnginx 1.4.1でサーバーを実行しています。現在、URL から末尾のスラッシュを削除し、301 リダイレクトを発行するようにセットアップしています。ただし、存在するディレクトリにアクセスすると、強制的にリダイレクト ループに陥ります。現在のドキュメント ルートは次のようになります。

- index.php (app)
- webgrind
    - index.php
- static 
    - css

現在、example.com/webgrind やその他のディレクトリにアクセスできません。私のアクセスログは次のように繰り返し読み取られます。

GET /webgrind/ HTTP/1.1" 301 178 "-"
GET /webgrind  HTTP/1.1" 301 178 "-"

これは私のnginx.confのサーバーブロックです:

server {
        listen 80;
        server_name example.com;

        location / {
            try_files $uri $uri/ /index.php?$args;
            root /var/www/example/public;
            index  index.php index.html index.htm;
        }

        rewrite ^/(.*)/$ /$1 permanent;

        location = /favicon.ico {
            access_log     off;
            log_not_found  off;
        }

        location ~ \.php$ {
            try_files $uri $uri/ /index.php?$args;
            root /var/www/example/public;
            index index.php index.html index.htm;

            fastcgi_pass   unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/example/public$fastcgi_script_name;
            fastcgi_param  APPLICATION_ENV testing;
            fastcgi_param  PATH /usr/bin:/bin:/usr/sbin:/sbin;
            fastcgi_intercept_errors on;
            include        fastcgi_params;
        }
    }

私はそれrewrite ^/(.*)/$ /$1 permanent;が問題のある行であることを認識しています。それを削除して example.com/webgrind にアクセスすると、example.com/webgrind/ はディレクトリであるため、301 が発行されてリダイレクトされます。ただし、私のアプリケーションは、末尾のスラッシュと末尾のスラッシュ以外の両方 (つまり、example.com/users/ と example.com/users) を受け入れるようになりましたが、これは私が望んでいるものではありません。

次のように「if」ディレクティブを書き換えの周りにラップしても、ディレクトリのリダイレクト ループが作成されます ( if は悪のようですが、この場合の書き換えディレクティブは安全と見なされます)。

if (!-d $request_filename) {
    rewrite ^/(.*)/$ /$1 permanent;
}

(webgrind/index.php にアクセスすれば問題が解決することはわかっていますが、本番ディレクトリがライブにプッシュされるときに、コストがかかり専門的でないリダイレクト ループは避けたいと考えています。)

では、存在しないリソース (Web アプリケーションのパス) の末尾のスラッシュのみを条件付きで削除するにはどうすればよいでしょうか?

更新: 私の (変更されていない) fastcgi_params 構成:

fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_FILENAME         $request_filename;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

fastcgi_param   HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;
4

1 に答える 1

9

ブロックの直接の子としてブロックrootの外側にディレクティブを配置すると、問題が修正されました。 locationserver

server {
    listen 80;
    server_name example.com;

    # This WORKS!
    root /var/www/example/public; 

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

    if (!-d $request_filename) {
        rewrite ^/(.*)/$ /$1 permanent;
    }

    location = /favicon.ico {
        access_log     off;
        log_not_found  off;
    }

    location ~ \.php$ {
        try_files $uri $uri/ /index.php?$args;
        index index.php index.html index.htm;

        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/example/public$fastcgi_script_name;
        fastcgi_param  APPLICATION_ENV testing;
        fastcgi_param  PATH /usr/bin:/bin:/usr/sbin:/sbin;
        fastcgi_intercept_errors on;
        include        fastcgi_params;
    }
}

どうやら、Nginx wiki が回避することを推奨している落とし穴です。

于 2013-11-03T13:43:44.053 に答える