如何使用htaccess拒绝浏览器请求url而不拒绝RewriteRule?

问题描述 投票:0回答:1

我想拒绝对文件的直接访问,但为该文件提供 RewriteRule

RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1
RewriteRule ^/image.php [L, R=404]

我希望 localhost/image.php 返回错误 404 但对于 localhost/image/image.jpg 也返回 404

.htaccess mod-rewrite
1个回答
0
投票

指令的顺序很重要!

具体来说,

mod_rewrite
Apache 模块按顺序处理每个请求的规则,后面的规则会看到前面规则操作的 URL

这实际上就是您使用的

[L]

 标志的用途 - 它是 
[last]
 的缩写,意味着“在当前上下文中不再处理此请求的任何规则”。 
稍微更强的形式是 [END]
,意思是“不再处理此请求的任何规则,即使新 URL 会重新处理 
.htaccess
 文件或 
<Directory>
 块”。


在您当前的规则中,对于

/image/hello.jpg

 的请求会发生以下情况:

    模式
  1. ^/image/([^/]+).jpg$
    /image/hello.jpg
     进行测试、匹配并将 URL 重写为 
    /image.php?name=hello
    
    
  2. 模式
  3. ^/image.php
    针对
    重写的URL进行测试,/image.php?name=hello
    匹配,并发出404

如果你把它们反过来说:

RewriteRule ^/image.php [L, R=404] RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1
现在,以下是对 

/image/hello.jpg

 的请求会发生的情况:

    模式
  1. ^/image.php
    /image/hello.jpg
    /image.php?name=hello
     进行测试,不匹配,因此不应用任何更改
  2. 模式
  3. ^/image/([^/]+).jpg$
    /image/hello.jpg
     进行测试、匹配并将 URL 重写为 
    /image.php?name=hello
    
    
  4. 但是,这些指令存在于
  5. .htaccess
     文件中,该文件将被重新处理,重复步骤 1

如果您在两条规则上也使用

[END]

RewriteRule ^/image.php [END, R=404] RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1 [END]
现在,以下是对 

/image/hello.jpg

 的请求会发生的情况:

    模式
  1. ^/image.php
    /image/hello.jpg
    /image.php?name=hello
     进行测试,不匹配,因此不应用任何更改
  2. 模式
  3. ^/image/([^/]+).jpg$
    /image/hello.jpg
     进行测试、匹配并将 URL 重写为 
    /image.php?name=hello
    
    
  4. [END]
    标志确保不再处理更多规则

事实上,在这种情况下添加

[END]

 就足以让它以任一顺序工作:

RewriteRule ^/image/([^/]+).jpg$ /image.php?name=$1 [END] RewriteRule ^/image.php [END, R=404]

    模式
  1. ^/image/([^/]+).jpg$
    /image/hello.jpg
     进行测试、匹配并将 URL 重写为 
    /image.php?name=hello
    
    
  2. [END]
    标志确保不再处理更多规则,因此
    ^/image.php
    规则甚至没有经过测试
© www.soinside.com 2019 - 2024. All rights reserved.