多个重写条件:如何在一组规则之前链接它们?

Posted

技术标签:

【中文标题】多个重写条件:如何在一组规则之前链接它们?【英文标题】:Multiple RewriteConditions: How to chain them before a set of rules? 【发布时间】:2011-07-15 10:15:42 【问题描述】:

Q1:如何将这两个条件链接起来使它们if BOTH A AND B, then proceed...Q2:如何使它们坚持所有重写下面的规则,而不仅仅是第一条规则?

RewriteCond %REQUEST_URI ^IMAGE-.*$      // if filename starts with IMG- and,
RewriteCond %REQUEST_FILENAME !-f        // if file does exist, then proceed:
RewriteRule Rule1
RewriteRule Rule2
RewriteRule Rule3

# -- END IF -- STOP HERE -- #

【问题讨论】:

你能把[L]标志放在最后一个吗?没有测试过,只是凭记忆思考... 【参考方案1】:

Q1:默认为 AND。

Q2:它们只会影响下面的 RewriteRule。

【讨论】:

+1 谢谢!正如亚历克斯在我的问题中评论的那样,添加 [L] 标志有什么不同吗? L 标志与您的问题无关。【参考方案2】:

你不能那样做。您必须重复您的 RewriteConds 或使用引用重新考虑您的重写规则,以便在一条规则中完成所有操作。第一条路线虽然不漂亮,但会是最简单的。所以

RewriteCond A
RewriteCond B
RewriteRule 1

RewriteCond A #duplicate
RewriteCond B #duplicate
RewriteRule 2

【讨论】:

@user @alex 对我的问题的评论如何,他说要在最后一个上添加 [L]? @Sam [L] 仅表示“对于此请求,请不要再执行这些规则。不适用于您的情况。更适合您说的情况:如果 URL 像 / blah/foo 然后做 A [L] 如果 URL 像 /blah 然后做 B。[L] 说停在这里,即使它符合第二个条件也不做 B。希望这是有道理的 :) @ChuckKollars 我也想到了[C],但这取决于RewriteRules 是什么。有时RewriteConds 是唯一真实的条件,RewriteRules 总是匹配的(例如RewriteRule ^ - [E=foo:42])。在规则总是匹配的情况下,[C] 是要走的路。另一方面,如果您的 RewriteRules 有可能不匹配的条件,您将在第一个不匹配的规则处停止处理 [C]s,这可能不是 OP 想要的。 @ChuckKollars RewriteRule 的语法是RewriteRule pattern subst [flags],对吧?例如,如果您有三个 RewriteRules 和不同的 patterns,并且您使用 [C] 将它们链接在一起,那么第一个不匹配的 pattern 将终止链:任何以下链式规则将不跑。我对 OP 的解读是,他们希望三个RewriteRules 都取决于前面的RewriteConds,我只是指出[C] 是在这种情况下使用的东西只要 保证所有规则的patterns 匹配。 @dale 我忘记了在我相当不寻常的环境中工作的东西通常不能正常工作。感谢您指出了这一点!我删除了我的 cmets,因为它们反映的环境比 OP 询问的更专业。【参考方案3】:

这里有一些技巧可以让RewriteCond 堆栈适用于多个RewriteRule,按递增WTF's per minute 排序。但这是配置而不是代码,所以这些规则不适用,对吧? :-)

1。环境变量

当您有许多 RewriteCond 时,将它们的结果存储在环境变量中,然后在每个规则中进行测试会更加紧凑。

# Your RewriteCond stack.
RewriteCond %REQUEST_URI !^IMAGE-.*$ [OR]
RewriteCond %REQUEST_FILENAME -f
# Store environment variable.
RewriteRule ^ - [E=TRUE:YEP]
# Assert environment variable in remaining RewriteRule's.
RewriteCond %ENV:TRUE =YEP
RewriteRule Rule1
RewriteCond %ENV:TRUE =YEP
RewriteRule Rule2
RewriteCond %ENV:TRUE =YEP
RewriteRule Rule3

2。跳过标志

这个有点微妙。使用[S][skip] 标志,您可以跳过整个RewriteRule 块。

# Your RewriteCond stack.
RewriteCond %REQUEST_URI !^IMAGE-.*$ [OR]
RewriteCond %REQUEST_FILENAME -f
# If RewriteCond's match, skip the next RewriteRule.
RewriteRule ^ - [skip=1]
# Otherwise, this rule will match and the rest will be skipped.
RewriteRule ^ - [skip=3]
RewriteRule Rule1
RewriteRule Rule2
RewriteRule Rule3

这有点像 if 语句,RewriteCond 是条件,RewriteRule 是代码块。

您获得的重复更少,但代价是代码不太清晰,每次您从这组 N RewriteRule' 中添加或删除规则时都必须更新 [skip=N]秒。

好吧,如果你还在阅读,在这里你会发现另外两个解决方案,WTF's per minute 达到并超过临界点。它们仅供娱乐,您会明白为什么。

3。跳过没有 N 的标志

是的,有一种方法可以使用[skip] 标志而不包括N,即您要应用RewriteCond 堆栈的RewriteRule 的数量。也就是说...如果您在每个 RewriteRule 之前添加一对 RewriteCond,哦,是的,最后还有一个。

# Your RewriteCond stack.
RewriteCond %REQUEST_URI !^IMAGE-.*$ [OR]
RewriteCond %REQUEST_FILENAME -f
# If RewriteCond's match, skip the next RewriteRule.
RewriteRule ^ - [skip=1]  # succeeded
RewriteRule ^ - [skip=2]  # failed
RewriteRule Rule1
RewriteRule ^ - [skip=1]  # succeeded
RewriteRule ^ - [skip=2]  # failed
RewriteRule Rule2
RewriteRule ^ - [skip=1]  # succeeded
RewriteRule ^ - [skip=2]  # failed
RewriteRule Rule3
RewriteRule ^ -           # no-op to cover for last [skip=2] rule

这里的诀窍是,当且仅当RewriteCond 成功时,每个[skip=1] 规则都会被处理,而当且仅当它们失败时,每个[skip=2] 规则才会被处理。

4。网址标记

使用部分 URL 来保持状态,然后在您的 RewriteRule 中匹配它。

# Your RewriteCond stack.
RewriteCond %REQUEST_URI !^IMAGE-.*$ [OR]
RewriteCond %REQUEST_FILENAME -f
# If RewriteCond's match, prepend bogus marker "M#" to internal URL.
RewriteRule .* M#$0
# All your RewriteRule's test for this marker plus whatever else.
RewriteRule ^M#.*Rule1
RewriteRule ^M#.*Rule2
RewriteRule ^M#.*Rule3
# Finally, don't forget to strip off the bogus marker.
RewriteRule ^M#(.*) $1

带有标记的新 URL 无效,但最后一个 RewriteRule 还原它,对吗?好吧,只有当它被处理时,所以不要让标记 URL 在它被还原之前逃脱这一轮 mod_rewrite 处理。然后你会得到一个 404。

【讨论】:

我不得不在办公室大声笑,感谢sorted by increasing WTF's per minute。以前从未听说过

以上是关于多个重写条件:如何在一组规则之前链接它们?的主要内容,如果未能解决你的问题,请参考以下文章

如何链接一组切换按钮,如单选按钮?

联结表

如何在Tomcat 9的rewrite.config文件中为多个角度项目添加多个重写规则

在一组运营商之间均匀分布尽可能多的物品

T-SQL 在一组条件中恰好有一个条件为真

如果条件不匹配,则重写规则