如何向 RewriteRule 添加条件以排除子目录中不存在的文件?
Posted
技术标签:
【中文标题】如何向 RewriteRule 添加条件以排除子目录中不存在的文件?【英文标题】:How can I add a condition to RewriteRule that would exclude files that do not exist in a subdirectory? 【发布时间】:2021-11-22 16:35:51 【问题描述】:如果页面不存在,我希望排除调用规则。在我现有的 htaccess 中,当用户从根目录访问不存在的页面时,此规则按预期工作。奇怪的是,如果用户试图访问一个不存在的有效页面的子目录,它就不起作用。
我的 htaccess 的当前行为:
example.com/valid-page/ -> example.com/valid-page/ (good)
example.com/valid-page -> example.com/valid-page/ (good)
example.com/valid-page/valid-page -> example.com/valid-page/valid-page/ (good)
example.com/does-not-exist -> example.com/does-not-exist (good)
example.com/valid-page/does-not-exist -> example.com/valid-page/does-not-exist/ (boo!)
对于上面的坏例子,期望的结果应该是不包含正斜杠:
example.com/valid-page/does-not-exist -> example.com/valid-page/does-not-exist
这是.htaccess:
# Redirects for errors
ErrorDocument 404 /error.php
ErrorDocument 403 /error.php
# Hides directory file listings
Options -Indexes
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# Force slash at end of URL
RewriteCond %REQUEST_URI /+[^\.]+$
RewriteCond %REQUEST_FILENAME.php -f
RewriteRule ^(.+[^/])$ %REQUEST_URI/ [R=301,L]
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %THE_REQUEST ^[A-Z]3,\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %SCRIPT_FILENAME !-d
RewriteRule ^([^.]+)/$ $1.php [NC,L]
【问题讨论】:
【参考方案1】:# Force slash at end of URL RewriteCond %REQUEST_URI /+[^\.]+$ RewriteCond %REQUEST_FILENAME.php -f RewriteRule ^(.+[^/])$ %REQUEST_URI/ [R=301,L]
您需要更改检查REQUEST_FILENAME
的第二个条件,因为当您请求/valid-page/does-not-exist
时,REQUEST_FILENAME
是.../valid-page
,而不是您所期望的.../valid-page/does-not-exist
。
代替REQUEST_FILENAME
,使用REQUEST_URI
(或$1
反向引用)并构造绝对文件名。例如:
# Force slash at end of URL
RewriteCond %REQUEST_URI /+[^\.]+$
RewriteCond %DOCUMENT_ROOT%REQUEST_URI.php -f
RewriteRule ^(.+[^/])$ %REQUEST_URI/ [R=301,L]
您需要在测试前清除浏览器缓存,因为错误的 301(永久)重定向将被浏览器缓存。使用 302(临时)重定向进行测试以避免缓存问题。
现在,当您请求 /valid-page/does-not-exist
时,您正在检查 .../valid-page/does-not-exist.php
是否作为文件存在,而不是像以前一样存在 .../valid-page.php
。
请参阅my answer 以了解有关 ServerFault 的以下问题,该问题更详细地了解了 REQUEST_FILENAME
的实际设置。 https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error
【讨论】:
以上是关于如何向 RewriteRule 添加条件以排除子目录中不存在的文件?的主要内容,如果未能解决你的问题,请参考以下文章