Nginx viết lại URL chỉ khi tập tin tồn tại


13

Tôi cần viết quy tắc viết lại cho Nginx để nếu người dùng cố gắng truy cập url hình ảnh cũ:

/images/path/to/image.png

và tập tin không tồn tại, hãy thử chuyển hướng đến:

/website_images/path/to/image.png

CHỈ nếu hình ảnh tồn tại trong URL mới, nếu không thì tiếp tục với 404. Phiên bản Nginx trên máy chủ của chúng tôi chưa có try_files.

Câu trả lời:


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

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

Mặc dù vậy, bạn có thể muốn sửa lỗi máy chủ của mình để nâng cấp hoặc tìm máy chủ tốt hơn.


Điều này sẽ chuyển hướng đến / new_images trên mỗi 404 phải không? Tôi không muốn viết lại trừ khi tôi biết tệp new_images tồn tại
Jose Fernandez

Điều này kiểm tra xem tệp có tồn tại không và nếu kiểm tra đó thất bại, nó sẽ chuyển hướng đến new_images. Điều gì xảy ra sau đó không được chỉ định ở đây.
tylerl

Tôi e rằng lựa chọn của bạn được coi là những cạm bẫy phổ biến của các tác giả nginx nginx.com/resource/wiki/start/topics/tutorials/config_pit thác / từ
dòng sông

2
@riverfall Heh, tôi đã viết một phần của trang đó. Câu trả lời của tôi đã được viết cách đây 8 năm nên có một chút lỗi thời, nhưng câu hỏi ban đầu đã nói rõ rằng máy chủ của họ không cung cấp phiên bản nginx gần đây nên họ không có quyền truy cập vào try_files.
Martin Fjordvald

1
@ Guillaume86 Tôi sẽ không lo lắng về điều đó, nếu + viết lại hoàn toàn an toàn và một kiểm tra STAT duy nhất trên một tệp có trọng lượng rất nhẹ. Nó nhanh hơn nhiều so với việc đi đến một ứng dụng phụ trợ để kiểm tra chế độ bảo trì.
Martin Fjordvald

6

Vui lòng không sử dụng ifbên trong khối vị trí. Những điều tồi tệ có thể xảy ra.

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

$1 trở thành tên tệp để thử trong chỉ thị try_files, được tạo cho những gì bạn đang cố gắng thực hiện.

Điều này, HOẶC, chỉ cần viết lại mà không cần kiểm tra. Nếu hình ảnh đó không có ở đó, bạn sẽ nhận được 404.


Mặc dù câu trả lời này hoàn toàn không trả lời câu hỏi ("[chưa] try_files", nhưng đối với những khách truy cập trong tương lai tới đây, câu trả lời này xứng đáng được nhiều phiếu bầu hơn.
DerMike

5

Bạn có thể sử dụng một cái gì đó như thế này (chưa được kiểm tra cho trường hợp cụ thể của bạn):

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

Về cơ bản, đó là một cách khác để viết các ifcâu lệnh lồng nhau , vì bạn không thể lồng trong Nginx. Xem ở đây để tham khảo chính thức về "hack" này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.