se pare că accesarea site.com/api/v1/ nu execută api_v1.php. În schimb, ar continua și ar executa index.php
Da, pentru că prima regulă rescrie cererea către api_v1.php
și asta ajunge să fie rescris index.php
prin a doua regulă (pentru că php
nu se află în lista extensiilor excluse din prima condiție, a doua condiție este de asemenea reușită, așa că a treia condiție nu este procesată - vezi mai jos) în timpul celei de-a doua treceri a motorului de rescrire. Într-o director context (ex. .htaccess
) cel L
flag nu oprește toate procesările, ci doar oprește trecerea curentului prin motorul de rescrire. Motorul de rescrire trece în buclă până când adresa URL trece neschimbată.
Puteți rezolva acest lucru pe Apache 2.4 folosind Sfârşit
steag, în loc de L
, pe prima regulă pentru a opri toate procesările de către motorul de rescriere.
De exemplu:
RewriteRule ^api/v1/ api_v1.php [NC,END]
(Am eliminat trailingul (.*)$
pe regex, deoarece nu este necesar aici și face ca regex-ul să fie marginal mai puțin eficient.)
Cu toate acestea, faptul că o cerere pentru un existent .php
fișierul este rescris de regulile tale ulterioare demonstrează cu adevărat că a doua și a treia regulă nu par să funcționeze așa cum a fost prevăzut...
#2. Rescrieți în index.php, cu excepția fișierelor design/document/favicon/roboți care există
RewriteCond %{REQUEST_URI} !.(css|js|png|jpg|jpeg|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$
RewriteCond %{REQUEST_URI} !^(roboți\.txt|favicon\.ico)$ [SAU]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L]
#3. Rescrie orice altceva
RewriteRule ^(.*)$ index.php [L]
Dacă solicitați ceva.php
apoi primul condiție are succes (pentru că .php
este nu incluse în listă). A doua condiție este de asemenea reușită (nu este robots.txt
sau favicon.ico
). Deoarece a doua condiție este în mod explicit OR cu a treia condiție, a treia condiție nu este procesată.Toate condițiile sunt reușite și cererea este rescrisă la index.php
(indiferent daca ceva.php
există sau nu).
Dacă, pe de altă parte, solicitați resursă.css
apoi primul condiție eșuează (pentru că are un .css
extensie). Deoarece această condiție este implicit AND'd, nu sunt procesate alte condiții și regula nu este declanșată. A treia regulă se rescrie apoi necondiționat resursă.css
la index.php
, indiferent dacă există sau nu!
Deci, acest lucru nu verifică dacă o resursă solicitată (css
, jpg
, etc.) „există” așa cum ar părea să implice comentariul precedent. A treia condiție (care verifică că cererea nu se mapează la un fișier) este procesată numai atunci când condiția anterioară OR eșuează ȘI prima condiție are succes. Cu alte cuvinte, a treia condiție este procesată doar atunci când solicitați /roboți.txt
- ceea ce sunt sigur că nu este intenția ta.
Cu alte cuvinte, regulile #2 și #3 (în ciuda complexității lor aparente) ar părea să se rescrie destul de mult Tot la index.php
.
Soluție completă
Pe baza comentariilor dvs. suplimentare:
Pentru un subset de tipuri de fișiere, serviți resursa - dacă aceasta există. Dacă resursa nu există, trimiteți cererea către index.php
.
Pentru alte tipuri de fișiere, trimiteți solicitarea la index.php
, indiferent dacă resursa respectivă există sau nu.
Câteva solicitări (ex. /roboți.txt
și /favicon.ico
) nu trebuie trimis la index.php
.
Încercați următoarele:
# Preveniți redirecționarea 301 cu bară oblică atunci când folderul există și nu are atașat o bară oblică
# Aceasta nu este o problemă de securitate aici, deoarece este folosit un router PHP și toate căile sunt redirecționate
DirectorySlash Off
# Deoarece „DirectorySlash Off” este setat, asigurați-vă că listările de directoare mod_auotindex sunt dezactivate
Opțiuni -Indici
RewriteEngine Pornit
#1. Rescrieți pentru adresa URL API
RewriteRule ^api/v1/ api_v1.php [NC,END]
#2. Adresele URL/fișierele cunoscute sunt difuzate direct
RewriteRule ^(index\.php|roboți\.txt|favicon\.ico)$ - [END]
#3.Anumite tipuri de fișiere (resurse) sunt servite direct dacă există
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.(css|js|png|jpe?g|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$ - [END]
#4. Rescrie totul
RewriteRule ^ index.php [END]
Regulile se termină mai devreme pentru orice trebuie servit direct, așa că trebuie doar să rescriem index.php
o dată în ultima regulă.
Rețineți că am inclus index.php
în regula #2. Aceasta este o optimizare, deși nu este strict necesară dacă se utilizează Sfârşit
steag (spre deosebire de L
) pe ultima regulă.
Opțional, puteți alege să redirecționați oricare direct solicită să index.php
înapoi la rădăcină (pentru canonizarea URL-ului pentru motoarele de căutare). Asta pentru orice eventualitate /index.php
este expus (sau ghicit) utilizatorului final.
De exemplu, adăugați următoarele după prima regulă pentru API:
#1.5 Redirecționați solicitările directe către „/index.php” înapoi la „/” (rădăcină)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ / [R=301,L]
The condiție care verifică împotriva REDIRECT_STATUS
variabila de mediu este necesară pentru a preveni o buclă de redirecționare - pentru a evita redirecționarea URL-ului rescris. (Deși, din nou, acest lucru nu este strict necesar dacă se utilizează Sfârşit
steag pe regula ultima/rescrie.)