2013-03-19 13 views
5

Questo sembra ridicolo ma non ho trovato una risposta funzionante in oltre un'ora di ricerca.reindirizzamento statico dell'indice nginx

Ho un sito Web statico in esecuzione su nginx (che si trova dietro a Varnish). Il file di indice si chiama index.html. Voglio reindirizzare chiunque visiti l'URL mydomain.com/index.html di nuovo allo mydomain.com.

Ecco il mio config nginx per il sito:

server { 
    listen 8080; 
    server_name www.mydomain.com; 
    port_in_redirect off; 

    location/{ 
    root /usr/share/nginx/www.mydomain.com/public; 
    index index.html; 
    } 

    rewrite /index.html http://www.mydomain.com/ permanent; 
} 

http://www.mydomain.com/index.html risponde come previsto con un 301 con la posizione http://www.mydomain.com/ ma purtroppo http://www.mydomain.com/ serve anche una 301 a se stessa in modo da ottenere un loop di reindirizzamento.

Come posso dire a nginx di servire solo il 301 se index.html è letteralmente nella richiesta?

risposta

7

Aggiungi un nuovo blocco di posizione per gestire la tua home page e utilizza la direttiva try_files (anziché "index index.html;") per cercare direttamente il file index.html. Nota che try_files richiede di inserire almeno 2 scelte. Quindi ho messo lo stesso file due volte.

location =/{ 
    root /usr/share/nginx/www.mydomain.com/public; 
    try_files /index.html /index.html; 
} 

Sembra buono in base alla mia esperienza:

curl -iL http://www.mydomain.com/index.html 
HTTP/1.1 301 Moved Permanently 
Server: nginx 
Date: Sat, 16 Mar 2013 09:07:27 GMT 
Content-Type: text/html 
Content-Length: 178 
Connection: keep-alive 
Location: http://www.mydomain.com/ 

HTTP/1.1 200 OK 
Server: nginx 
Date: Sat, 16 Mar 2013 09:07:27 GMT 
Content-Type: text/html 
Content-Length: 4 
Last-Modified: Sat, 16 Mar 2013 08:05:47 GMT 
Connection: keep-alive 
Accept-Ranges: bytes 

[UPDATE] La causa principale del loop di reindirizzamento è la direttiva 'indice', che innesca nginx di fare un altro giro di posizione abbinare di nuovo. È così che la regola di riscrittura esterna al blocco di posizione viene nuovamente eseguita, causando il loop. Quindi la direttiva 'indice' è come una "riscrittura ... ultima;" direttiva. Non lo vuoi nel tuo caso.

Il trucco è di non attivare nuovamente un'altra corrispondenza di posizione. try_files può farlo in modo efficiente. Ecco perché l'ho scelto nella mia risposta originale. Tuttavia, se si vuole, un altro semplice soluzione è quella di sostituire

index index.html; 

da

rewrite ^/$ /index.html break; 

all'interno del vostro "/ posizione" blocco originale. Questa 'riscrittura ... interrompe;' la direttiva manterrà nginx all'interno dello stesso blocco di posizione, fermando effettivamente il ciclo. Tuttavia, l'effetto collaterale di questo approccio è che si perde la funzionalità fornita dalla direttiva "indice".

[UPDATE 2 ]

In realtà, la direttiva indice viene eseguito dopo direttiva riscrittura. Quindi funziona anche il seguente. Nota che ho appena aggiunto la riscrittura ... break; linea. Se la richiesta uri è "/", nginx trova prima il file /index.html esistente dalla regola di riscrittura. Quindi la direttiva index non viene mai attivata per questa richiesta. Di conseguenza, entrambe le direttive possono lavorare insieme.

location/{ 
    root /usr/share/nginx/www.mydomain.com/public; 
    index index.html; 
    rewrite ^/$ /index.html break; 
    } 
+0

Grazie, funziona. Non capisco davvero perché questo fermi il ciclo di reindirizzamento, ma lo fa. 'try_files' è un po 'magico forse. Puoi spiegare perché la linea 'try_files /index.html /index.html;' nel blocco posizione _existing_ non funziona? (Ci ho provato). Saluti. – Ade

+0

Poiché @ chuan-ma ha risolto il tuo problema, non dimenticare di contrassegnare la sua risposta come accettata :) –

+0

@Ade ti spiegherò più tardi stasera. –

-1

Sembra che tu sia davvero non vuoi che index.php compaia nella barra degli indirizzi, è corretto?

Se si aggiunge una direttiva di riscrittura alla configurazione di nginx, si otterrà un ciclo di reindirizzamento, come si è verificato. Se si sono aperti ad una soluzione javascript, è possibile inserire questo in qualsiasi punto della index.html di riscrivere in silenzio nella barra degli indirizzi:

<script> 
    history.pushState(null, '', '/'); 
</script> 

For more information

Tenete a mente che, mentre la maggior parte dei browser moderni supportano il history API, non tutti lo fanno (vale a dire, la maggior parte delle versioni di IE).

+0

Grazie; sì, conosco diversi metodi a livello di applicazione per eseguire il reindirizzamento, ma ho voluto che questo fosse configurato a livello di server poiché deve essere riutilizzato in un certo numero di applicazioni. – Ade