try_files ทำงานอย่างไร


72

ฉันดูเอกสาร nginx และมันยังทำให้ฉันสับสนอย่างที่สุด

อย่างไรtry_filesทำงานอย่างไร นี่คือสิ่งที่เอกสารบอกว่า:

จาก NginxHttpCoreModule

try_files

ไวยากรณ์: try_files path1 [path2] uri

เริ่มต้น: ไม่มี

บริบท: เซิร์ฟเวอร์, ตำแหน่ง

ห้องว่าง: 0.7.27

ตรวจสอบการมีอยู่ของไฟล์ตามลำดับและส่งคืนไฟล์แรกที่พบ สแลชต่อท้ายบ่งชี้ไดเรกทอรี - $ uri / ในกรณีที่ไม่พบไฟล์การเปลี่ยนเส้นทางภายในไปยังพารามิเตอร์สุดท้ายจะถูกเรียกใช้ พารามิเตอร์สุดท้ายคือทางเลือก URI และ ต้องมีอยู่มิฉะนั้นจะเกิดข้อผิดพลาดภายใน ซึ่งแตกต่างจากการเขียนใหม่ $ args จะไม่ถูกเก็บไว้โดยอัตโนมัติหากทางเลือกไม่ใช่ตำแหน่งที่ระบุชื่อ หากคุณต้องการเก็บรักษา args คุณต้องทำอย่างชัดเจน:

ฉันไม่เข้าใจวิธีการตรวจสอบเส้นทางและจะทำอย่างไรหากฉันไม่ต้องการข้อผิดพลาดภายใน แต่ให้เริ่มเส้นทางที่เหลือต่อเพื่อหาไฟล์อื่น

หากฉันต้องการลองใช้ไฟล์แคช/path/app/cache/url/index.htmlและหากล้มเหลวในการลอง/path/app/index.phpฉันจะเขียนมันได้อย่างไร ถ้าฉันเขียนว่า:

try_files /path/app/cache/ $uri
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;

index index.php index.html index.htm;ฉันมี เมื่อฉันเยี่ยมชม/urlnameจะลองตรวจสอบ/path/app/cache/urlname/index.phpแล้ว/path/app/cache/urlname/index.htmlหรือไม่ ถ้าเราไม่สนใจทุกอย่างหลังจากtry_filesเป็นไปได้สำหรับtry_filesการตรวจสอบโฟลเดอร์แคช? ฉันพยายามแล้วและล้มเหลว

คำตอบ:


64

try_files พยายามพา ธ ตัวอักษรที่คุณระบุโดยสัมพันธ์กับคำสั่งรูทที่กำหนดและตั้งค่าตัวชี้ไฟล์ภายใน หากคุณใช้อินสแตนซ์try_files /app/cache/ $uri @fallback;ด้วยindex index.php index.html;มันจะทดสอบเส้นทางตามลำดับนี้:

  1. $document_root/app/cache/index.php
  2. $document_root/app/cache/index.html
  3. $document_root$uri

ก่อนที่จะเปลี่ยนเส้นทางภายในไปยัง @fallback ที่มีชื่อสถานที่ในที่สุด นอกจากนี้คุณยังสามารถใช้ไฟล์หรือรหัสสถานะ ( =404) เป็นพารามิเตอร์สุดท้ายของคุณ แต่ถ้าใช้ไฟล์มันต้องมีอยู่

คุณควรทราบว่า try_files นั้นจะไม่ทำการเปลี่ยนเส้นทางภายในสำหรับสิ่งใดนอกจากพารามิเตอร์สุดท้าย หมายความว่าคุณไม่สามารถทำสิ่งต่อไปนี้: try_files $uri /cache.php @fallback;เนื่องจากจะทำให้ nginx ตั้งค่าตัวชี้ไฟล์ภายในเป็น $ document_root / cache.php และให้บริการ แต่เนื่องจากไม่มีการเปลี่ยนเส้นทางภายในเกิดขึ้นสถานที่จึงไม่ได้รับการประเมินใหม่และจะเป็นเช่นนั้น ทำหน้าที่เป็นข้อความธรรมดา (เหตุผลที่ทำงานกับไฟล์ PHP เนื่องจากดัชนีคือคำสั่งดัชนีจะออกการเปลี่ยนเส้นทางภายใน)


2
นั่นชัดเจนมากขึ้น ขอบคุณ ฉันไม่แน่ใจเล็กน้อยว่าตำแหน่งที่ตั้งชื่อทำงานอย่างไร หาก @fallback มีบรรทัดสำหรับ fastcgi php ที่จะใช้เป็นไฟล์ php แทนที่จะเป็นข้อความหรือไม่? ใช้ทางเลือกก่อนทุกอย่างก่อนที่มันจะล้มเหลวหรือไม่?

2
ตำแหน่งที่ระบุชื่อนั้นมีหน้าที่เหมือนกับตำแหน่งปกติยกเว้นสามารถเข้าถึงได้ผ่านกลไกภายในเช่น error_page และ try_files เท่านั้น fallback ใน try_files ถูกใช้เมื่อไม่มีเส้นทางที่ระบุส่งผลให้ไฟล์ที่ถูกต้อง คุณยังคงต้องมีตำแหน่งเพื่อจับ \ .php $ URIs มิฉะนั้น try_files จะเปิดใช้งาน $ uri หากมีไฟล์อยู่และใช้เป็นข้อความธรรมดา
Martin Fjordvald

ขอบคุณสำหรับคำตอบนี้ .. ฉันยังมีคำถามอยู่ที่นี่: try_files ดำเนินการทันทีหรือจะลองใช้ตำแหน่งที่ซ้อนกันมาก่อนหรือไม่
Stphane

@Stphane คุณกำลังจะย้ายไปที่น่านน้ำมืดครึ้มที่นี่ การสืบทอดใน nginx นั้นซับซ้อนยุ่งเหยิงและไม่สอดคล้องกันทั้งหมด ฉันต้องตรวจสอบบันทึกเก่าของฉันเพียงเพื่อจดจำสิ่งนี้ดังนั้นจึงไม่มีการรับประกัน แต่ดูเหมือนว่าสำหรับ try_files โดยเฉพาะเมื่อจัดการกับตำแหน่งที่ซ้อนกันเท่านั้นจะไม่ทำงานหากตำแหน่งด้านในตรงกัน ฉันขอแนะนำให้ทำการทดสอบ
Martin Fjordvald

5

นี่คือการใช้ try_files ที่สะดวกอีกแบบหนึ่งเนื่องจากการเปลี่ยนเส้นทางแบบไม่มีเงื่อนไขไปยังตำแหน่งที่ระบุชื่อ ตำแหน่งที่ระบุชื่อทำหน้าที่เป็นรูทีนย่อยอย่างมีประสิทธิภาพช่วยประหยัดการทำซ้ำของรหัส เมื่ออาร์กิวเมนต์แรกของ try_files คือ "_" การเปลี่ยนเส้นทางสำรองจะถูกใช้เสมอ

    location =/wp-login.php { try_files _ @adminlock; }
    location ^~ /wp-admin/  { try_files _ @adminlock; }
    location @adminlock  {
            allow 544.23.310.198;
            deny all;
            try_files _ @backend;
            # wp-admin traffic is tiny so ok to send all reqs to backend 
    }
    location ~ \.php {  try_files _ @backend; }
    location / { try_files $uri $uri/ =403; }
    location @backend {
            fastcgi_pass 127.0.0.1:9000;
            include snippets/fastcgi-php.conf;
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.