![Apache mod_rewrite,在 RewriteCond 中使用当前 URL](https://linux22.com/image/487006/Apache%20mod_rewrite%EF%BC%8C%E5%9C%A8%20RewriteCond%20%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%BD%93%E5%89%8D%20URL.png)
我在 Apache VirtualHost 配置中有几个 RewriteRules。我希望能够根据某些条件测试当前 URL(在前面的重写之后)。问题是变量 %REQUEST_URI 是在处理开始时设置的,并且在每条规则之后都不会改变。关于这些变量的文档很少;是否有某种方法可以使用 RewriteCond 来针对当前 URL 进行测试?
我已启用重写日志,很明显,即使在第一个 RewriteRule 匹配并重写之后,%REQUEST_URI 仍然设置为“/”
#Map '/' and '' to '/home'
RewriteRule ^/?$ /home
#Check for cached page
RewriteCond %{DOCUMENT_ROOT}/system/cache%{REQUEST_URI}.html -f
RewriteRule ^(.+)$ /system/cache/$1.html [QSA,L]
有什么简单的方法可以实现这一点吗?
编辑: 这是 RewriteLog 的摘录,我不认为发生了内部子请求。
(3) applying pattern '^/?$' to uri '/'
(2) rewrite '/' -> '/home'
(3) applying pattern '^([^.]+)$' to uri '/home'
(4) RewriteCond: input='/var/www/vhosts/example.com/subdomains/demo/rails/public/system/cache/.html' pattern='-f' => not-matched
(3) applying pattern '^.*$' to uri '/home'
(4) RewriteCond: input='/var/www/vhosts/example.com/subdomains/demo/rails/public/system/maintenance.html' pattern='-f' => not-matched
(3) applying pattern '^/(.*)$' to uri '/home'
(4) RewriteCond: input='/home' pattern='!-f' => matched
(2) rewrite '/home' -> 'http://127.0.0.1:8100/home'
(2) forcing proxy-throughput with http://127.0.0.1:8100/home
(1) go-ahead with proxy request proxy:http://127.0.0.1:8100/home [OK]
答案1
您可以通过反向引用访问“当前”URI。来自 RewriteRule 文档...
测试字符串是一个字符串,除了纯文本外,还可以包含以下扩展结构:
- RewriteRule 反向引用:这些是形式为
$N
(0 <= N <= 9) 的反向引用,它们提供从符合当前条件集的 RewriteRule 对模式的分组部分(在括号中)的访问RewriteCond
。
您还可以更干净地处理初始斜杠 - 请求 URI 始终以 开头/
。 (您可以发出的最短请求是GET / HTTP/1.0
。)解决方案是...
# Map '/' to '/home'
RewriteRule ^/$ /home
# Check for cached page
RewriteCond %{DOCUMENT_ROOT}/system/cache/$1.html -f
RewriteRule ^/(.+)$ /system/cache/$1.html [QSA,L]
答案2
主要问题:您不必担心。是的,您的第二条规则不会匹配初始请求,但您的重写/home
将生成一个内部子请求,然后该子请求将匹配缓存规则。
附带问题:$1
当我们的意思是$1
. :) 时,我们使用 。 :) $0
指的是整个模式匹配,其中$1
指的是匹配中的第一个捕获组(带括号的块)。 (这确实意味着您的第二条规则可以很容易地写成RewriteRule .+ /system/cache/$0.html
。 不过,人们通常认为这不如像您那样使用显式捕获那么清楚。)