2013-08-24 2 views
5

Я запускаю сервер на nginx 1.4.1 с PHP-FastCGI. В настоящее время у меня есть настройка так, что она удаляет трейлинг-косы из моих URL-адресов и выдает 301 переадресацию. Однако, когда я нахожусь в каталоге, который существует, я вынужден в цикл переадресации. Мой текущий корень документа выглядит следующим образом:Как удалить конечную косую черту из URL-адреса в nginx только в том случае, если каталог не существует?

- 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, мне будет отправлено 301 для перенаправления на example.com/webgrind/, так как это каталог. Тем не менее, мое приложение теперь будет принимать как конечные, так и незаметные косые черты (например, example.com/users/ и example.com/users), и это не то, что я хочу.

Обертывание «если» директивы вокруг моих переписывают следующим образом все еще создает цикл перенаправления для моих каталогов (if is evil, по-видимому, но директива переписывает в этом случае считается безопасной):

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

(I что посещение webgrind/index.php решит мою проблему, но я бы хотел избежать дорогостоящих и непрофессиональных циклов переадресации, когда мои производственные каталоги перетаскиваются в реальном времени.)

Итак, как я могу условно отделить трейлинг-косыми чертами только для ресурсов которые не существуют (мое веб-приложение n путей)?

UPDATE: Мое (без изменения) 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; 
+0

Несколько вещей: 1) Я не уверен, что полностью понимаю, чего вы пытаетесь достичь с точки зрения поведения для удаления конечной косой черты - пытаетесь ли вы перенаправить на серверный уровень, где, если клиент отправляет либо ' foo.com/aaa' или 'foo.com/aaa /', чтобы сервер ответил документом; или вы пытаетесь заставить сервер указывать браузеру перенаправлять с 'foo.com/aaa /' на 'foo.com/aaa'? –

+0

2) Я не могу воспроизвести цикл перенаправления, если я использую блок 'if'. Возможно, вы столкнулись с проблемой, если используете более старый браузер - см. [Переадресация переадресации кэшей Internet Explorer 9] (http://agsci.psu.edu/it/how-to/topics/web/web-development/plone/ другие/internet-explorer-9-постоянно-кэши-перенаправления) для одного примера. Итак, что это значит, даже с блоком «if», IE будет пытаться перенаправить, поскольку у него был старый кеш-код перезаписи. Чтобы решить эту проблему, вам необходимо очистить кеш браузера. –

+0

@chuex Я пытаюсь заставить сервер указать клиенту перенаправление с foo.com/aaa/ на foo.com/aaa с ответом 301. Я тестировал последние Chrome и Firefox на двух разных компьютерах и очистил кеш, и я все еще получаю эту проблему. – danronmoon

ответ

5

Ввод root директивы вне location блока в качестве прямого потомка server блока, закрепленного вопрос.

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; 
    } 
} 

Видимо это pitfall, что вики Nginx рекомендует избегать.

+0

Просто для того, чтобы расширить свой ответ - ловушка с наличием корневой директивы внутри блока местоположения состоит в том, что другие блоки местоположения не имеют корневой директивы. (Если они не имеют собственных дублированных корневых директив.) Если корневая директива находится на уровне сервера, то она применяется ко всем блокам местоположения. –

+0

Я считаю, что проверка if для каталога была той, которая исправила проблему ... – Daniel