Nginx menulis ulang URL hanya jika file ada

13

Saya perlu menulis aturan penulisan ulang untuk Nginx sehingga jika pengguna mencoba membuka url gambar lama:

/images/path/to/image.png

dan file tidak ada, cobalah untuk mengarahkan ulang ke:

/website_images/path/to/image.png

HANYA jika gambar ada di URL baru, jika tidak lanjutkan dengan 404. Versi Nginx pada host kami belum memiliki try_files.

Jose Fernandez
sumber

Jawaban:

19
location /images/ {
    if (-f $request_filename) {
        break;
    }

    rewrite ^/images/(.*) /new_images/$1 permanent;
}

Meskipun demikian, Anda mungkin ingin meng-bug host Anda untuk meningkatkan atau menemukan host yang lebih baik.

Martin Fjordvald
sumber
Ini akan mengarahkan ulang ke / new_images pada setiap 404 kan? Saya tidak ingin melakukan penulisan ulang kecuali saya tahu file new_images ada
Jose Fernandez
Ini memeriksa untuk melihat apakah file itu ada, dan jika tes itu gagal, itu diarahkan ke new_images. Apa yang terjadi setelah itu tidak ditentukan di sini.
tylerl
Saya khawatir pilihan Anda dianggap sebagai perangkap umum oleh penulis nginx nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
riverfall
2
@ Heverfall Heh, saya menulis bagian dari halaman itu. Jawaban saya ditulis 8 tahun yang lalu jadi ya itu agak ketinggalan jaman, tetapi pertanyaan aslinya memang secara khusus menyatakan bahwa host mereka tidak menyediakan versi nginx terbaru sehingga mereka tidak memiliki akses ke try_files.
Martin Fjordvald
1
@ Guillaume86 Saya tidak akan khawatir tentang itu, jika + penulisan ulang benar-benar aman dan satu STAT memeriksa pada file sangat ringan. Ini jauh lebih cepat daripada pergi ke aplikasi backend untuk memeriksa mode pemeliharaan.
Martin Fjordvald
6

Harap jangan gunakan ifdi dalam blok lokasi. Hal-hal buruk dapat terjadi.

location ~* ^/images/(.+)$ {
    root /www;
    try_files /path/to/$1 /website_images/path_to/$1 /any/dir/$1 @your404;
}

$1 menjadi nama file untuk dicoba dalam arahan try_files, yang dibuat untuk apa yang ingin Anda capai.

Ini, ATAU, tulis ulang saja tanpa memeriksa. Jika gambar itu tidak ada, Anda akan mendapatkan 404.

Garet Claborn
sumber
Sementara jawaban ini ketat tidak menjawab pertanyaan ( "[ada] try_filesbelum"), untuk masa depan pengunjung datang ke sini, jawaban ini pantas lebih up-orang.
DerMike
5

Anda dapat menggunakan sesuatu seperti ini (tidak diuji untuk kasus spesifik Anda):

location ^/images/(?<imgpath>.*)$ {

    set $no_old  0;
    set $yes_new 0;

    if (!-f $request_filename)
    {
        set $no_old 1;
    }

    if (-f ~* "^/new_path/$imgpath")
    {
        set $yes_new 1$no_old;
    }

    # replacement exists in the new path
    if ($yes_new = 11)
    {
        rewrite ^/images/(.*)$ /new_path/$1 permanent;
    }

    # no image in the new path!
    if ($yes_new = 01)
    {
        return 404;
    }
}

Yang pada dasarnya merupakan cara alternatif menulis ifpernyataan bersarang , karena Anda tidak dapat bersarang di Nginx. Lihat di sini untuk referensi resmi tentang "retasan" ini.

tmslnz
sumber