2013-03-19 15 views
5

Wydaje się to śmieszne, ale nie znalazłem działającej odpowiedzi w ciągu ponad godziny poszukiwań.Przekierowanie statycznego indeksu nginx

Mam statyczną stronę internetową uruchomioną nginx (która dzieje się za Varnish). Plik indeksu nosi nazwę index.html. Chcę przekierować każdego, kto faktycznie odwiedza adres URL mydomain.com/index.html z powrotem na mydomain.com.

Oto moja nginx config na stronie:

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 reaguje zgodnie z oczekiwaniami z 301 z lokalizacją http://www.mydomain.com/ ale niestety http://www.mydomain.com/ służy również do 301 z powrotem do siebie, więc możemy uzyskać pętlę przekierowania.

Jak mogę powiedzieć, że nginx obsługuje tylko 301, jeśli index.html jest dosłownie w żądaniu?

Odpowiedz

7

Dodaj nowy blok lokalizacji do obsługi swojej strony głównej i użyj dyrektywy try_files (zamiast "index index.html;"), aby bezpośrednio wyszukać plik index.html. Zauważ, że try_files wymaga wprowadzenia co najmniej 2 opcji. Więc dwukrotnie umieściłem ten sam plik.

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

Wygląda dobrze w oparciu o moje doświadczenia:

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] Przyczyną pętlę przekierowania jest dyrektywą „Index”, który wyzwala nginx zrobić kolejną rundę lokalizacji dopasuj ponownie. W ten sposób reguła przepisywania poza blokiem lokalizacji zostanie ponownie wykonana, powodując pętlę. Tak więc dyrektywa "indeksu" jest jak "przepisanie ... ostatnie"; dyrektywa. Nie chcesz tego w swoim przypadku.

Podstęp polega na tym, aby ponownie nie wywoływać dopasowania do innej lokalizacji. try_files może to zrobić wydajnie. Dlatego wybrałem to w mojej oryginalnej odpowiedzi. Jednakże, jeśli chcesz, kolejna prosta poprawka ma zastąpić

index index.html; 

przez

rewrite ^/$ /index.html break; 

wewnątrz swojej pierwotnej lokalizacji "/" bloku. To "przeróbka ... przerwa"; dyrektywa sprawi, że nginx pozostanie w tym samym bloku lokalizacji, skutecznie zatrzyma pętlę. Jednak efektem ubocznym tego podejścia jest utrata funkcjonalności zapewnianej przez dyrektywę "index".

[UPDATE 2]

Właściwie dyrektywy wskaźnik wykonuje po dyrektywy przepisywania. Tak więc działa również poniższe. Zauważ, że właśnie dodałem przepisanie ... break; linia. Jeśli uri ma postać "/", nginx najpierw znajduje istniejący plik/index.html z reguły przepisywania. Dlatego dyrektywa indeksu nigdy nie jest wyzwalana dla tego żądania. W rezultacie obie dyrektywy mogą ze sobą współpracować.

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

Dzięki, to działa. Naprawdę nie rozumiem, dlaczego to zatrzymuje pętlę przekierowania, ale robi to. "try_files" może być nieco magiczne. Czy możesz wyjaśnić, dlaczego wstawianie linii 'try_files/index.html/index.html;' do bloku _istniejący_ lokalizacja nie działa? (Próbowałem tego). Twoje zdrowie. – Ade

+0

Ponieważ @ chuan-ma rozwiązał twój problem, nie zapomnij oznaczyć odpowiedzi jako zaakceptowanej :) –

+0

@Ade wyjaśnię później wieczorem. –

-1

Wygląda na to, że naprawdę nie chcesz, aby index.php pojawiał się na pasku adresu, czy to prawda?

Jeśli dodasz dyrektywę przepisywania do konfiguracji nginx, dostaniesz pętlę przekierowań, tak jak doświadczyłeś. Jeśli jesteś otwarty na rozwiązania JavaScript, można umieszczać w dowolnym miejscu index.html dyskretnie przepisać pasek adresu:

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

For more information

pamiętać, że podczas gdy większość nowoczesnych przeglądarek obsługuje history API, a nie wszystko to (a mianowicie, większość wersji IE).

+0

Dzięki; Tak, znam kilka sposobów przekierowania na poziomie aplikacji, ale chciałem, aby to zostało skonfigurowane na poziomie serwera, ponieważ ma być ponownie wykorzystane w wielu aplikacjach. – Ade

Powiązane problemy