ดูเหมือนว่าการเข้าถึง site.com/api/v1/ จะไม่เรียกใช้งาน api_v1.php แต่จะดำเนินการต่อและเรียกใช้งาน index.php
ใช่ เนื่องจากกฎข้อแรกเขียนคำขอใหม่เป็น api_v1.php
และสิ่งนี้จบลงด้วยการเขียนใหม่ index.php
ตามกฎข้อที่สอง (เพราะ php.ini
ไม่ได้อยู่ในรายการส่วนขยายที่ยกเว้นในตอนแรก เงื่อนไขเงื่อนไขที่สองก็สำเร็จเช่นกัน ดังนั้นเงื่อนไขที่สามจึงไม่ได้รับการประมวลผล - ดูด้านล่าง) ระหว่างรอบที่สองของกลไกเขียนใหม่ ใน ไดเรกทอรี บริบท (เช่น .htaccess
) ที่ แอล
แฟล็กไม่ได้หยุดการประมวลผลทั้งหมด แต่จะหยุดการผ่านปัจจุบันผ่านเอ็นจิ้นการเขียนซ้ำ เอ็นจิ้นการเขียนซ้ำจะวนซ้ำจนกว่า URL จะผ่านไปโดยไม่มีการเปลี่ยนแปลง
คุณสามารถแก้ไขปัญหานี้บน Apache 2.4 ได้โดยใช้ไฟล์ จบ
ธง แทน แอล
ตามกฎข้อแรกให้หยุดการประมวลผลทั้งหมดโดยโปรแกรมเขียนใหม่
ตัวอย่างเช่น:
RewriteRule ^api/v1/ api_v1.php [NC,END]
(ผมลบคำต่อท้าย (.*)$
ใน regex เนื่องจากไม่จำเป็นที่นี่ และทำให้ regex มีประสิทธิภาพน้อยลงเล็กน้อย)
อย่างไรก็ตามข้อเท็จจริงที่ว่าขอที่มีอยู่ .php
ไฟล์ถูกเขียนใหม่โดยกฎในภายหลังของคุณ แสดงให้เห็นว่ากฎข้อที่สองและสามของคุณดูเหมือนจะไม่ทำงานตามที่ตั้งใจไว้...
#2. เขียนใหม่เป็น index.php ยกเว้นสำหรับไฟล์ design/document/favicon/robots ที่มีอยู่
RewriteCond %{REQUEST_URI} !.(css|js|png|jpg|jpeg|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$
RewriteCond %{REQUEST_URI} !^(robots\.txt|favicon\.ico)$ [หรือ]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L]
#3. เขียนซ้ำสิ่งอื่นใด
RewriteRule ^(.*)$ index.php [L]
หากคุณร้องขอ บางสิ่งบางอย่าง.php
จากนั้นเป็นครั้งแรก เงื่อนไข ประสบความสำเร็จ (เพราะ .php
เป็น ไม่ รวมอยู่ในรายการ) เงื่อนไขที่สองก็สำเร็จเช่นกัน (ไม่ใช่ โรบ็อต.txt
หรือ favicon.ico
). เนื่องจากเงื่อนไขที่สองนั้นชัดเจนหรือขัดแย้งกับเงื่อนไขที่สาม เงื่อนไขที่สามจึงไม่ถูกประมวลผลเงื่อนไขทั้งหมดสำเร็จและคำขอจะถูกเขียนใหม่ index.php
(ไม่ว่าจะ บางสิ่งบางอย่าง.php
มีอยู่หรือไม่)
ถ้าในทางกลับกันคุณร้องขอ ทรัพยากร.css
จากนั้นเป็นครั้งแรก เงื่อนไข ล้มเหลว (เพราะมีไฟล์ .css
การขยาย). เนื่องจากเงื่อนไขนี้เป็นแบบ AND โดยปริยาย จึงไม่มีการประมวลผลเงื่อนไขเพิ่มเติมและกฎจะไม่ทำงาน กฎข้อที่สามจะเขียนใหม่โดยไม่มีเงื่อนไข ทรัพยากร.css
ถึง index.php
ไม่ว่าจะมีอยู่หรือไม่ก็ตาม!
ดังนั้น นี่จะไม่ตรวจสอบว่าทรัพยากรที่ร้องขอ (css
, jpg
ฯลฯ) "มีอยู่" ตามที่ดูเหมือนจะบอกเป็นนัยในความคิดเห็นก่อนหน้า เงื่อนไขที่สาม (ที่ตรวจสอบว่าคำขอไม่ได้แมปกับไฟล์) จะได้รับการประมวลผลก็ต่อเมื่อเงื่อนไข OR ก่อนหน้าล้มเหลว และเงื่อนไขแรกสำเร็จ กล่าวอีกนัยหนึ่ง เงื่อนไขที่ 3 จะดำเนินการเมื่อคุณร้องขอเท่านั้น /robots.txt
- ซึ่งผมแน่ใจว่าไม่ใช่เจตนาของคุณ
กล่าวอีกนัยหนึ่ง กฎข้อที่ 2 และข้อที่ 3 (แม้จะดูซับซ้อนก็ตาม) ดูเหมือนจะเป็นการเขียนใหม่ค่อนข้างมาก ทุกอย่าง ถึง index.php
.
โซลูชั่นที่สมบูรณ์
ตามความคิดเห็นเพิ่มเติมของคุณ:
สำหรับชุดย่อยของประเภทไฟล์ ให้บริการทรัพยากร - หากมีอยู่ หากไม่มีทรัพยากรให้ส่งคำขอไปที่ index.php
.
สำหรับไฟล์ประเภทอื่น ๆ ให้ส่งคำขอไปที่ index.php
โดยไม่คำนึงว่าทรัพยากรนั้นมีอยู่หรือไม่
คำขอเล็กน้อย (เช่น /robots.txt
และ /favicon.ico
) ไม่ควรส่งไปที่ index.php
.
ลองทำสิ่งต่อไปนี้แทน:
# ป้องกันการเปลี่ยนเส้นทาง 301 ด้วยเครื่องหมายทับเมื่อมีโฟลเดอร์อยู่และไม่ได้ใส่เครื่องหมายทับ
# นี่ไม่ใช่ปัญหาด้านความปลอดภัยเนื่องจากใช้เราเตอร์ PHP และเส้นทางทั้งหมดถูกเปลี่ยนเส้นทาง
DirectorySlash ปิด
# เนื่องจากมีการตั้งค่า "DirectorySlash Off" ตรวจสอบให้แน่ใจว่ารายการไดเรกทอรี mod_auotindex ถูกปิดใช้งาน
ตัวเลือก -ดัชนี
RewriteEngine เปิดอยู่
#1. เขียนใหม่สำหรับ API url
RewriteRule ^api/v1/ api_v1.php [NC,END]
#2. URL/ไฟล์ที่รู้จักจะถูกส่งโดยตรง
RewriteRule ^(index\.php|robots\.txt|favicon\.ico)$ - [จบ]
#3.ไฟล์บางประเภท (ทรัพยากร) จะให้บริการโดยตรงหากมีอยู่
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.(css|js|png|jpe?g|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$ - [จบ]
#4. เขียนใหม่ทั้งหมดอื่น
RewriteRule ^ index.php [จบ]
กฎเสร็จสิ้นก่อนเวลาสำหรับทุกสิ่งที่ต้องให้บริการโดยตรง ดังนั้นเราจำเป็นต้องเขียนใหม่เท่านั้น index.php
ครั้งเดียวในกฎข้อสุดท้าย
โปรดทราบว่าฉันได้รวม index.php
ในกฎข้อที่ 2 นี่คือการเพิ่มประสิทธิภาพ แม้ว่าจะไม่จำเป็นอย่างยิ่งหากใช้ จบ
ธง (ตรงข้ามกับ แอล
) ในกฎข้อสุดท้าย
หรือคุณอาจเลือกที่จะเปลี่ยนเส้นทางก็ได้ โดยตรง ขอให้ index.php
กลับไปที่รูท (เพื่อบัญญัติ URL สำหรับเครื่องมือค้นหา) นี่เป็นเพียงในกรณีที่ /index.php
เปิดเผย (หรือเดา) ต่อผู้ใช้ปลายทาง
ตัวอย่างเช่น เพิ่มสิ่งต่อไปนี้หลังจากกฎข้อแรกสำหรับ API:
#1.5 เปลี่ยนเส้นทางคำขอโดยตรงไปที่ "/index.php" กลับไปที่ "/" (รูท)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ / [R=301,L]
เดอะ เงื่อนไข ที่ตรวจสอบกับ REDIRECT_STATUS
ตัวแปรสภาพแวดล้อมเป็นสิ่งจำเป็นเพื่อป้องกันการวนรอบการเปลี่ยนเส้นทาง - เพื่อหลีกเลี่ยงการเปลี่ยนเส้นทาง URL ที่เขียนใหม่ (แม้ว่าจะไม่จำเป็นอย่างยิ่งหากใช้ไฟล์ จบ
แฟล็กในกฎสุดท้าย/เขียนใหม่)