为什么使用RewriteCond和RewriteRule来测试url条件?



在许多重写规则的答案中,当测试某个特定条件的url时,我经常看到混合使用RewriteCond和REQUEST_URI,以及RewriteRule本身。

这只是个人偏好,还是出于性能原因,或者只是为了明确规则?在我看来,所有这些都是合理的理由;我只是想知道是否有什么特别的原因。

我知道在某些情况下RewriteCond是唯一的选择。在这里,我感兴趣的是rewriterrule也可以工作的情况。一般来说,这些规则都比较简单。

下面是一些例子:

示例1

这个答案有一个共同的模式,允许某些文件夹保持原样。Htaccess维护模式允许某些目录

# always allow these folders
RewriteCond %{REQUEST_URI} ^/display_me_always [OR]
RewriteCond %{REQUEST_URI} ^/another_folder [OR]
RewriteCond %{REQUEST_URI} ^/even_more_folders
RewriteRule .+ - [L]

这可以通过一个rewriterrule来实现:

RewriteRule ^/(?:display_me_always|another_folder|even_more_folders) - [L]

(添加?:表示非捕获。我不太确定是使用更简单的规则更快,还是不使用。

示例2

将此修改为更常见的场景,将某些文件夹重定向到其他文件夹。

RewriteCond %{REQUEST_URI} ^/display_me_always [OR]
RewriteCond %{REQUEST_URI} ^/another_folder [OR]
RewriteCond %{REQUEST_URI} ^/even_more_folders
RewriteRule ^/[^/]+/(.*)$ /other_location/$1 [L]

只使用规则似乎更简单。

RewriteRule ^/(?:display_me_always|another_folder|even_more_folders)/(.*)$ /other_location/$1 [R=301,NC]

示例3

这个答案有一个共同的模式,如果不在目标位置,则重定向。Mod重写规则重定向所有pdf请求到另一个位置。用RewriteCond测试文件夹,然后用规则测试文件。

我可以看到RewriteCond的否定条件更清楚,但它仍然可能与RewriteRule。

RewriteCond %{REQUEST_URI} !^/web_content/pdf/
RewriteRule ^(.+.pdf)$ /web_content/pdf/$1 [L]

可以写成

RewriteRule ^(?!/web_content/pdf/)(.+.pdf)$ /web_content/pdf/$1 [L]

一个简单的原因:对于非正则表达式专家来说更容易理解。

您今天给OP的重写规则,他可能需要在一天后修改。规则越容易理解,他就越有可能自己去研究它,而不是再跑到这个地方去做另一个小修改/新的类似规则。

是的,组合规则更快——这里毫无疑问。但是,与单个脚本执行相比,花在URL重写上的时间仍然很小……只有在CPU非常繁忙的服务器上,当有很多这样的重写时,它才会有所不同。

因此,最优的将是介于之间的东西——它仍然易于阅读,同时又紧凑高效。而不是
# always allow these folders
RewriteCond %{REQUEST_URI} ^/display_me_always [OR]
RewriteCond %{REQUEST_URI} ^/another_folder [OR]
RewriteCond %{REQUEST_URI} ^/even_more_folders
RewriteRule .+ - [L]

提供
# always allow these folders
RewriteCond %{REQUEST_URI} ^/(display_me_always|another_folder|even_more_folders)
RewriteRule .+ - [L]

你不可能在一两天内成为大师(除非你是某种天才)——任何事情都需要时间。并且您拥有的实践经验越多(通过自己修改这些规则),就越有利于您继续前进,生成更有效/稳定的规则。

顺便说一句:如果将此规则放在。htaccess中(匹配模式中的URL以没有斜杠开头),该规则将不起作用:

RewriteRule ^/(?:display_me_always|another_folder|even_more_folders) - [L]

但是如果放在服务器配置/虚拟主机上下文中会工作得很好——这是你需要知道的"细微差别"之一

一般来说,我会说你是对的:RewriteCond实际上主要用于匹配条目而不是REQUEST_URI。我希望你们在。htaccess中看到的大多数情况。来自规范:

如果您希望匹配每个目录(htaccess) rewriterrule中的完整url路径,请在RewriteCond中使用%{REQUEST_URI}变量

最新更新