Nginx เขียน URL ใหม่เฉพาะในกรณีที่ไฟล์มีอยู่


13

ฉันต้องเขียนกฎการเขียนซ้ำสำหรับ Nginx ดังนั้นหากผู้ใช้พยายามไปที่ URL รูปภาพเก่า:

/images/path/to/image.png

และไฟล์ไม่มีอยู่ลองเปลี่ยนเส้นทางไปที่:

/website_images/path/to/image.png

หากรูปภาพนั้นมีอยู่ใน URL ใหม่มิฉะนั้นจะดำเนินการต่อด้วย 404 เวอร์ชันของ Nginx บนโฮสต์ของเรายังไม่มีไฟล์ try_files

คำตอบ:


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

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

แม้ว่าคุณอาจต้องการบั๊กโฮสต์ของคุณเพื่ออัพเกรดหรือค้นหาโฮสต์ที่ดีกว่า


สิ่งนี้จะเปลี่ยนเส้นทางไปที่ / new_images ในทุกๆ 404 ใช่ไหม ฉันไม่ต้องการเขียนใหม่เว้นแต่ฉันจะรู้ว่าไฟล์ new_images มีอยู่แล้ว
Jose Fernandez

สิ่งนี้จะตรวจสอบว่าไฟล์นั้นมีอยู่หรือไม่และการทดสอบนั้นล้มเหลวหรือไม่ไฟล์นั้นจะเปลี่ยนเส้นทางไปที่ new_images จะเกิดอะไรขึ้นหลังจากนั้นไม่ได้ระบุที่นี่
tylerl

ฉันกลัวว่าตัวเลือกของคุณจะถือเป็นข้อผิดพลาดที่พบบ่อยโดยผู้เขียน nginx nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/ …
Riverfall

2
@riverfall Heh ฉันเขียนส่วนหนึ่งของหน้านั้น คำตอบของฉันถูกเขียนเมื่อ 8 ปีที่แล้วดังนั้นใช่มันล้าสมัยไปแล้ว แต่คำถามเดิมระบุว่าโฮสต์ของพวกเขาไม่ได้ให้ nginx รุ่นล่าสุดดังนั้นพวกเขาจึงไม่สามารถเข้าถึง try_files ได้
Martin Fjordvald

1
@ Guillaume86 ฉันไม่ต้องกังวลเกี่ยวกับเรื่องนี้การเขียน + ใหม่ทั้งหมดจะปลอดภัยและการตรวจสอบสถานะไฟล์เดียวนั้นมีน้ำหนักเบามาก มันเร็วกว่าการใช้แอพพลิเคชั่นแบ็กเอนด์เพื่อตรวจสอบโหมดการบำรุงรักษา
Martin Fjordvald

6

โปรดอย่าใช้ifภายในบล็อกตำแหน่ง สิ่งเลวร้ายอาจเกิดขึ้น

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

$1 เป็นชื่อไฟล์เพื่อลองในคำสั่ง try_files ซึ่งทำเพื่อสิ่งที่คุณพยายามจะทำให้สำเร็จ

สิ่งนี้หรือเพียงแค่เขียนใหม่โดยไม่ตรวจสอบ หากภาพนั้นไม่มีคุณจะได้รับ 404 ต่อไป


ในขณะที่คำตอบนี้อย่างเคร่งครัดไม่ตอบคำถาม ( "[ไม่มี] try_filesเลย") สำหรับผู้เข้าชมในอนาคตมาที่นี่คำตอบนี้สมควรได้รับการขึ้นลงคะแนนเสียง
DerMike

5

คุณสามารถใช้สิ่งนี้ (ไม่ได้ทดสอบสำหรับกรณีเฉพาะของคุณ):

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

ซึ่งโดยทั่วไปเป็นอีกวิธีหนึ่งในการเขียนข้อความที่ซ้อนกันifเนื่องจากคุณไม่สามารถซ้อนใน Nginx ได้ ดูที่นี่สำหรับการอ้างอิงอย่างเป็นทางการของ "แฮ็ค" นี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.