Come rimuovere barra rovesciata da URL nginx solo se la directory non esiste?

Sono in esecuzione un server nginx 1.4.1 con PHP FastCGI. Attualmente ho la configurazione in modo che rimuove slash dal mio Url e i problemi di un redirect 301. Tuttavia, quando si visita una directory che esiste, io sono costretto in un loop di reindirizzamento. Il mio attuale radice del documento simile a questo:

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

Attualmente io non posso entrare example.com/webgrind o qualsiasi altra directory. Il mio log di accesso ripetutamente la lettura simile a:

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

Questo è il blocco del server nel mio 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;
        }
    }

Sono consapevole che rewrite ^/(.*)/$ /$1 permanent; è la riga incriminata. Se lo rimuovi e visita example.com/webgrind un 301 è rilasciato per me reindirizzare example.com/webgrind/dal momento che si tratta di una directory. Tuttavia, la mia domanda ora accettare entrambi i finali e non slash (es. example.com/users/e example.com/users) e questo non è quello che voglio.

Avvolgere il ‘se’, la direttiva in giro per la mia riscrivere come segue ancora crea un loop di redirect per il mio directory (se è male, a quanto pare, ma una riscrittura della direttiva in questo caso è considerato sicuro):

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

(So che la visita webgrind/index.php si potrebbe risolvere il mio problema, ma vorrei evitare costose e poco professionale reindirizzare loop quando la mia produzione directory sono spinto dal vivo.)

Come posso condizionale della striscia di slash solo per le risorse che non esistono (la mia applicazione web percorsi)?

AGGIORNAMENTO: il Mio (inalterato) fastcgi_params config:

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;
Un paio di cose: 1) io non sono sicuro di capire completamente ciò che si sta cercando di ottenere in termini di comportamento per la rimozione della barra finale – state cercando di ottenere un livello di server di reindirizzamento, dove se il client invia foo.com/aaa o foo.com/aaa/ che il server risponderà con un documento; o stai cercando di ottenere il server per dire al browser per reindirizzare dal foo.com/aaa/ per foo.com/aaa?
2) non riesco a riprodurre il loop di redirect, se io uso il if blocco. Si può vedere il problema se si utilizza un vecchio browser, vedere Internet Explorer 9 Permanentemente Cache Reindirizza ad esempio. Quello che significa è che anche con i “se” blocco, CIOÈ cerca di reindirizzare dal momento che era la vecchia riscrivere nella cache. Per risolvere questo problema devi cancellare la cache del browser.
Sto cercando di ottenere il server a dire il client per il reindirizzamento da foo.com/aaa/ a foo.com/aaa con un 301 risposta. Ho testato sui più recenti di Chrome e Firefox su 2 computer diversi e cancellato la cache e sto ancora ricevendo questo problema.
Con if blocco non posso riprodurlo… c’È qualche record in nginx errore.il log? E può essere che, per caso, l’applicazione reindirizza il wrongfolder per wrongfolder/(creando così il ciclo infinito stesso, in lotta con nginx)?
Non ci sono record in nginx log di errore per quanto riguarda il loop di redirect, e io non sono sorpreso perché 301 sono le normali operazioni. Non sono sicuro di cosa si intende per wrongfolder… io sono 100% positive queste cartelle presenti, se è quello che stai chiedendo. Se la directory non esiste, la mia app (index.php) si sarebbe preso cura di routing (questo è quello che /index.php?$args sta facendo). Mi sento meglio ora che ci sono 2 casi di if blocco di lavoro, quindi forse la mia produzione di installazione per risolvere il problema. Potresti postare un link al tuo test config? Posso inviare il mio http blocco, ma non so se potrebbe aiutare

OriginaleL’autore danronmoon | 2013-08-24

1 risposta

  1. 7

    Mettere il root direttiva al di fuori della location blocco come un figlio diretto del server blocco risolto il problema.

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

    A quanto pare è un insidia che il Nginx wiki raccomanda di evitare.

    Solo per espandere la tua risposta – la trappola con avere il root direttiva all’interno di un blocco di posizione è che gli altri blocchi di posizione quindi non hanno una radice direttiva. (A meno che non hanno una loro duplicati radice direttive.) Se la radice direttiva è a livello di server, quindi si applica a tutti i blocchi di posizione.
    Credo che se la clausola di verifica per una directory, è stato quello di risolvere il problema…

    OriginaleL’autore danronmoon

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *