我想拒绝对文件的直接访问,但为该文件提供 RewriteRule
RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1
RewriteRule ^/image.php [L, R=404]
我希望 localhost/image.php 返回错误 404 但对于 localhost/image/image.jpg 也返回 404
指令的顺序很重要!
具体来说,
mod_rewrite
Apache 模块按顺序处理每个请求的规则,后面的规则会看到前面规则操作的 URL。
这实际上就是您使用的 [L]
标志的用途 - 它是
[last]
的缩写,意味着“在当前上下文中不再处理此请求的任何规则”。稍微更强的形式是
[END]
,意思是“不再处理此请求的任何规则,即使新 URL 会重新处理 .htaccess
文件或
<Directory>
块”。
/image/hello.jpg
的请求会发生以下情况:
^/image/([^/]+).jpg$
与
/image/hello.jpg
进行测试、匹配并将 URL 重写为
/image.php?name=hello
^/image.php
针对重写的URL进行测试,
/image.php?name=hello
匹配,并发出404
RewriteRule ^/image.php [L, R=404]
RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1
现在,以下是对 /image/hello.jpg
的请求会发生的情况:
^/image.php
与
/image/hello.jpg
、
/image.php?name=hello
进行测试,不匹配,因此不应用任何更改
^/image/([^/]+).jpg$
与
/image/hello.jpg
进行测试、匹配并将 URL 重写为
/image.php?name=hello
.htaccess
文件中,该文件将被重新处理,重复步骤 1
[END]
:
RewriteRule ^/image.php [END, R=404]
RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1 [END]
现在,以下是对 /image/hello.jpg
的请求会发生的情况:
^/image.php
与
/image/hello.jpg
、
/image.php?name=hello
进行测试,不匹配,因此不应用任何更改
^/image/([^/]+).jpg$
与
/image/hello.jpg
进行测试、匹配并将 URL 重写为
/image.php?name=hello
[END]
标志确保不再处理更多规则
[END]
就足以让它以任一顺序工作:
RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1 [END]
RewriteRule ^/image.php [END, R=404]
^/image/([^/]+).jpg$
与
/image/hello.jpg
进行测试、匹配并将 URL 重写为
/image.php?name=hello
[END]
标志确保不再处理更多规则,因此
^/image.php
规则甚至没有经过测试