【问题标题】:Why use RewriteCond and RewriteRule to test a url condition?为什么要使用 RewriteCond 和 RewriteRule 来测试一个 url 条件?
【发布时间】:2011-11-08 20:33:16
【问题描述】:

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

这只是个人喜好,还是有性能原因,或者只是规则的明确性?在我看来,所有这些都是正当的理由;我只是想知道是否有特殊原因。

我知道在某些情况下 RewriteCond 是唯一的选择。我对 RewriteRule 也可以工作的情况感兴趣。通常这些是更简单的规则。

这里有一些例子:

示例 1

这个答案有一个共同的模式,允许某些文件夹按原样。 Htaccess maintenance mode allow certain directories

# 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]

这可以通过一个 RewriteRule 来完成:

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 Rewrite rule to redirect all pdf request to another location。使用 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]

【问题讨论】:

    标签: .htaccess url-rewriting


    【解决方案1】:

    总的来说,我会说你是对的:RewriteCond 实际上主要用于匹配项以外的 REQUEST_URI。我希望您在.htaccess 中查看的大多数案例。来自spec

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

    【讨论】:

      【解决方案2】:

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

      您今天将给 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]
      

      但如果放在服务器配置/虚拟主机上下文中会正常工作 - 这是您需要了解的“细微差别”之一。

      【讨论】:

      • 感谢您的洞察力。我是设计时胜过运行时的忠实拥护者。在学习 v3(和 mod_rewrite)之前,我来自 isapi_rewrite v2。所以我通常是非常非常复杂的 RewriteRule 规则的专家,但从来没有像这样拿起 RewriteCond。现在我可以开始简化了。
      • 是的,我的意思是要评论一下斜杠是这里的变量;我们将 .htaccess 作为单独网站 (isapi_rewrite) 中的“唯一”规则文件进行了演变,为了明确起见,我倾向于使用空的 RewriteBase 以斜线开头所有规则。在回答通用 .htaccess 问题时,我将开始倾向于使用 mod_rewrite 约定。
      • 一个小补充:很多使用 URL 重写的人都知道RewriteRule .* - [F,L] 中的.* 会做什么(我在这里跳过了 RewriteCond)。但是他们中的很多人仍然会惊讶于^ in RewriteRule ^ - [F,L] 会做同样的事情并且会更快(取决于 URL 的长度——越长,正则表达式引擎匹配 @987654328 所需的步骤越多@)。他们中的大多数人都不知道^ 自己做了什么。是的 .. 具体的事情可能 .. 但只是复杂性/效率与可读性的又一个例子。
      猜你喜欢
      • 1970-01-01
      • 2018-02-18
      • 2012-03-21
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      相关资源
      最近更新 更多