I am making an API in which I had those .htaccess
rules to make "friendly URLs", so I can make Endpoints that doesn't depend on the presence of a file that matches the URI:
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . /index.php [L,NC,QSA]
</IfModule>
The intent of the first rule is: "if requested filename (in the URL) is not an existing file or directory, then redirect to index.php
" . It works very well for that matter.
The intent for the second rule is: "if requested filename is an existing directory, then redirect to index.php
" . It also works like a charm.
The problem is that now, I need to fit in a Frontend developed with React.js by another developer, so I need to apply some exceptions to those rules. I tried the following changes to the second .htaccess
rule:
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !^/directory_a.*
RewriteCond %{REQUEST_URI} !^/directory_a/directory_b.*
RewriteRule . /index.php [L,NC,QSA
...which intent is like: "if requested filename is an existing directory, and requested URI doesn't start with /directory_a
neither with /directory_a/directory_b
, then and only then redirect to index.php
" . The rule works, but it isn't enough, because it still redirects existing files within those directories. So, in order to fix that, I tried the following:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !^/directory_a.*
RewriteCond %{REQUEST_URI} !^/directory_a/directory_b.*
RewriteRule . /index.php [L,NC,QSA
...almost the same than the previous modification, but asking for existing files as well. Here, I guess the conditions would work (expressed as pseudo-code) like this (but I'm not sure about it at all), prioritizing OR
over AND
:
IF ( is_existing_file OR is_existing_directory )
AND NOT uri.startswith( '/directory_a' )
AND NOT uri.startswith( '/directory_a/directory_b' )
...anyway, this is not working: it makes the Apache
server to crash with an HTTP 500
(Internal Server Error) that throws the following error in error_log
:
AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
...I wonder why this happens at all, and if is it possible to achive what I am trying to achieve here via .htaccess
...
My API is deployed in DocumentRoot
, as well as it's index.php
and .htaccess
file.
You may use these rules:
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# ignore rules below this for URIs starting with /directory_a/
RewriteCond %{THE_REQUEST} \s/+directory_a[/?\s]
RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . /index.php [L]
</IfModule>
Note that we are using THE_REQUEST
here, which doesn't change after executing rewrite rules. REQUEST_URI
on the other hand gets updated after executing rewrite rules
It seems that excluding index.php
in the conditions, solves the problem. Thanks, @DusanBajic:-)
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteCond %{REQUEST_URI} !^/directory_a.*
RewriteCond %{REQUEST_URI} !^/directory_a/directory_b.*
RewriteRule . /index.php [L,NC,QSA]
</IfModule>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.