Rewrite all files to index.php except sitemap.xml
I am trying to redirect every php file to index.php except sitemap.xml. The problem is that sitemap.xml is redirected also to index.php. How to redirect all php files to index.php and sitemap.xml to sitemap.php ?
RewriteEngine On RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s([^.]+) [NC] RewriteRule ^ %1 [R=301,L] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^/?(.*).php$ index.php [L,QSA] RewriteRule sitemap.xml sitemap/sitemap.php [L]
你需要一个额外的RewriteCond来排除sitemap.php,否则当sitemap.php被请求时,它将满足两个条件!-d
和-f
并且将被重写为index.php
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s([^.]+) [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} !/(sitemap.php)/
RewriteRule ^/?(.*).php$ index.php [L,QSA]
RewriteRule sitemap.xml sitemap/sitemap.php [L]
sitemap.xml
is being rewritten to sitemap/sitemap.php
, but then the rewriting process starts over (in .htaccess
) and sitemap/sitemap.php
then gets rewritten to index.php
on the second pass.
You should include an "exception" at the top of the file for any existing .php
file that you want to allow direct access. For example:
RewriteRule ^(index|sitemap/sitemap).php$ - [L]
This will prevent /index.php
and /sitemap/sitemap.php
from being processed by the directives that follow (and being rewritten to index.php
). index.php
currently "works" simply because mod_rewrite later detects you are writing back to itself and ignores the second rewrite.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s([^.]+) [NC]
RewriteRule ^ %1 [R=301,L]
Aside: I'm not sure what this is supposed to be doing, but I don't think this is doing what you think it's doing? In fact, I don't think this is doing anything!? The trailing backslash (escape char) on the CondPattern is the concern here. It looks like you are trying to match the space after the request URL (and before the protocol), but that is not what is going to happen here, at the end of the CondPattern. The "problem" is that the space is also the argument delimiter in Apache config files. In order to match a space at the end of the pattern you should either use the s
(any white-space character) shorthand character class, or enclose the CondPattern in double-quotes, or include the first few chars of the protocol (eg. HTTP
). For example:
RewriteCond %{THE_REQUEST} ^[AZ]{3,}s([^.]+)s
RewriteCond %{THE_REQUEST} "^[AZ]{3,}s([^.]+) "
(escaping the space is optional if enclosed in double quotes) RewriteCond %{THE_REQUEST} ^[AZ]{3,}s([^.]+) HTTP
The NC
flag is mostly superfluous unless you are trying to also catch invalid requests? Any legitimate browser request will have the method and protocol all uppercase.
However, if this did match (with the trailing space) then you would get a redirect loop for any URL that did not contain a .
(literal dot). So, either way, it does not look correct. (?)