Nginx'te yedek hata sayfası nasıl ayarlanır?


10

Şu anda nginx'in bazı hata sayfalarını ve diğer "varsayılan" medya dosyalarını (favicon.ico ve robots.txt gibi) işlemesini yapılandırıyorum ve bazı hata sayfaları için istediğim şekilde çalışmak için küçük bir problemle karşılaştım .

Temel olarak, yapmaya çalıştığım şey o sunucu için kök altında bir sunucu için belirli dosyaları sunmak, örneğin /var/www/someserver.com/robots.txt. Bu dosya yoksa, nginx "varsayılan", yani /var/www/default/robots.txt gitmek istiyorum. Bu (başarıyla) yapılandırılmış nasıl temel özüdür:

server {
    ...
    root /var/www/someserver.com;

    location ~* ^/(robots\.txt)$ {
        error_page 404 = @default;
    }

    location @default {
        root /var/www/default;
    }
}

Harika çalışıyor.

Hata sayfaları için de aynı şeyi yapmaya çalışıyorum ve bunun olmasına rağmen yapamıyorum:

server {
    ...
    root /var/www/someserver.com;

    error_page 404   /404.html;

    location ~* ^/(404\.html)$ {
        error_page 404 = @default;
    }

    location @default {
        root /var/www/default;
    }
}

Bunun someserver.com/404.html adresini ziyaret ederseniz, önce /var/www/someserver.com/404.html dosyasını yüklemeyi ve ardından / var / www / default'a geri dönmeyi denemesi anlamında "işe yaradığını" unutmayın. /404.html bulunmazsa. Ancak, someserver.com/blahblah adresini ziyaret ederseniz, yalnızca /var/www/someserver.com/ adresinde ayarlanmışsa 404 sayfasını gösterir. Bu dosya yoksa varsayılan dizine düşmez.

Her neyse, muhtemelen yapmaya çalıştığım şeyi yapabilirsiniz (bu yüzden ilk çalışma örneğini ekledim).

Herhangi bir fikir?

Düzenle:

Martin F'nin cevabına dayanarak, bir araya getirdim:

# Doesn't work when error page is returned on a POST request
server {
    ...
    root /var/www/someserver.com;

    error_page  404         = @notfound;
    error_page  500 502 504 = @server_error;
    error_page  503         = @maintenance;

    location @notfound {
        try_files /404.html /../default/404.html =404;
    }

    location @server_error {
        try_files /500.html /../default/500.html =500;
    }

    location @maintenance {
        try_files /503.html /../default/503.html =503;
    }
}

Bu harika çalışıyor. Hata_sayfaları ve yukarıdaki konumların gerçek bloğu, her sanal ana bilgisayara dahil edilen bir server_defaults.conf dosyasındadır, bu yüzden her bir konuma giden yolu zor kodlamamıştım ve varsayılanlar için göreceli bir yol kullandım.

Düzenleme 2:

Bu yaklaşımın bir sorunu var. Hata döndüren bir URL'ye POST yaparsanız, POST istek yöntemi try_files girişimleriyle gönderilir. Bu (benim için) bir 405 İzin Verilmez hatasıyla sonuçlanır, çünkü nginx aslında sadece bu sayfayı almak yerine /default/500.html adresine POST göndermeye çalışır.

Düzenleme 3:

Orijinal fikrimden çok daha yakın olan bir çözüm yayınladım.

Yanıtlar:


10

Sonunda orijinal fikrime çok daha yakın bir şeyle devam ettim. Kaybettiğim anahtarın direktif olduğu ortaya çıktı recursive_error_pages. Gerçekten tek yapmam gereken bunu "açmak "tı ve orijinal fikrim işe yaradı. Conf benim ilgili kısmı şimdi şöyle görünüyor:

server {
    ...

    root /var/www/someserver.com/;

    error_page 400 404      /404.html;
    error_page 500 502 504  /500.html;
    error_page 503          /503.html;

    recursive_error_pages   on;

    location ~* ^/(404\.html|500\.html|503\.html)$ {
        log_not_found off;
        error_page 404 = @default;
    }

    location @default {
        log_not_found on;
        root /var/www/default;
    }
}

Buradaki orijinal sorumun parçası olmayan diğer hata türlerini de ekledim çünkü bu, Martin F'nin yaklaşımıyla ilgili zorluklara neden oldu, aksi takdirde mükemmeldi. log_not_foundYönerge sadece hata sayfası orijinal kökünde bulunan değilken benim günlüğüne 404'lerin alamadım sağlar.


Bu harika çalışıyor (özellikle 404 / POST kombinasyonu), ancak HTTP Hata kodunu yutuyor ve 200 gönderiyor gibi ... Benim yaptığımla aynı davranışa sahip misiniz?
Ekim

2
Bunun yerine kaldırmak log_not_found off;ve eklemek isteyebilirsiniz internal;.
Alix Axel

Bir POST isteğinde hataya neden olan sorun nginx'in tuhaf davranışıdır, bkz. Trac.nginx.org/nginx/ticket/824
Robo

5

try_files buraya gitmenin yolu. Aşağıdaki yapılandırma çalışmalıdır, ancak sözdizimi hataları için test etmedim.

server {
    ...
    root /var/www;

    location / {
        try_files /someserver.com$uri /default$uri /someserver.com$uri/ /default$uri/ @notfound;
    }

    location @notfound {
       try_files /someserver/404.html /default/404.html =404; # =404 should make it use the nginx-default 404 page.
    }
}

Evet, tam da ihtiyacım olan şey bu. Try_files kullanmayı denemiştim ama cevabınız, bunun için özel bir dahili konum oluşturmam gerektiğini fark etmemi sağladı. Cevabımı, benim için çalışan yapılandırmayı göstermek için düzenledim, bu da önerilerinizde birkaç değişiklik yapıldı.
Jim D

Yukarıdaki düzenleme 2'ye bakın. Ne söyleyebilirim, bu öneri POST istekleri ile çalışmaz. Try_files, orijinal isteğin istek yöntemini kullandığından, 405 İzin Verilmez yanıtı alırsınız.
Jim D

@JimD: Bu yaklaşımı tam olarak kullanmıyorsunuz, değiştirilmiş bir yaklaşımı kullanıyorsunuz. Bu benim için çalışıyor.
0.8.x'den

Sorun, ben sadece 404s için bu kullanıyorum, bu yüzden konum yerine - hata_sayfa -> konum -> try_files yapmak zorunda -> try_files -> konum -> try_files gibi. Ancak ben bir paket bir 0.7.x ikili, bu yüzden onu kaynağından inşa ve çözer olmadığını görmeye çalışacağım.
Jim D

2

Maalesef cevabımdan birkaç yıl geç kaldım, ancak gelecekteki araştırmacılara yardımcı olabileceğini düşündüm. Yüklü Nginx sürümüm 1.2.4 ve aşağıdaki yapılandırma snippet'ini oluşturdum,

server {

server_name www.example.com
root /var/www/example


## Errors -> Locations
error_page   400 /400.html;
error_page   403 /403.html;
error_page   404 /404.html;
error_page   500 502 503 504 /50x.html;

## Locations -> Fallback
location = /400.html {
    try_files /400.html @error;
    internal;
}
location = /403.html {
    try_files /403.html @error;
    internal;
}
location = /404.html {
    try_files /404.html @error;
    internal;
}
location = /50x.html {
    try_files /50x.html @error;
    internal;
}

## Fallback Directory
location @error {
    root /var/www/error;
}

}

1
İyi kullanımı internal.
Clint Pachl

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.