Apache .htaccess中单个重写条件的多个重写规则

Apache .htaccess中单个重写条件的多个重写规则,apache,.htaccess,mod-rewrite,Apache,.htaccess,Mod Rewrite,我在.htaccess中有以下命令 RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC] RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L] RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L] %2在第二行和以后的行中不起作用。 我可以为%2定义任何变量并在所有重写规则命令中使用它吗? 以下命令起作用 Re

我在.htaccess中有以下命令

    RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
    RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
    RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]
%2在第二行和以后的行中不起作用。 我可以为%2定义任何变量并在所有重写规则命令中使用它吗? 以下命令起作用

     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([a-z]+) %2/$1.$2 [L]
     RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
     RewriteRule ^(.*?)-([0-9]+)([a-z]) %2/$1$3.$2 [L]

但是我希望对多个规则行使用%2,而不需要重复条件。

必须将变量保存为Apache变量,这样就可以在没有重复条件的情况下使用该变量

第二行显示保存在Apache变量中。在第三行和第四行中使用保存的VAR

RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9-]+)\.example\.com [NC]
RewriteRule .? - [E=Wa:%1,E=Wb:%2]
RewriteRule ^(.*?)-([a-z]+) %{ENV:Wb}/$1.%{ENV:Wb} [L]
RewriteRule ^(.*?)-([0-9]+)([a-z]) %{ENV:Wb}/$1$3.$2 [L]

您可以使用RewriteRule标志
S | skip
将多个RewriteRules绑定到单个RewriteCond(或一组RewriteCond)。下面是一个将一个条件应用于三个规则的示例:

RewriteCond  %{HTTP_HOST}  !^www.mydomain.com$
# skip rules if NOT within domain - only way to tie multiple rules to one cond
RewriteRule  .?  -  [S=3]
RewriteRule  ^path1(/.*)$  /otherpath1$1
RewriteRule  ^path2(/.*)$  /otherpath2$1
RewriteRule  ^path3(/.*)$  /otherpath3$1
要将现有条件更改为适用于多个规则,您必须:

  • 否定条件(在条件前面加上!)
  • 如果有多个重写条件:
    将条件中的逻辑and更改为OR,反之亦然
  • 在要绑定到条件的所有规则之前添加跳过重写规则。将S参数设置为要跳过的规则行数

请注意,在跳过的规则中,不可能使用任何指向重写条件(如%1)的反向引用。这些只有在跳过重写规则中才能访问。

显然,这并不是什么有趣的事情,尤其是当事情变得越来越复杂时。然而,RewriteRule语句有一个不太为人所知的选项,它告诉apache跳过下一个N个RewriteRule语句。[S=N]。因此,我们可以这样做,而不是每次都检查请求是否不是文件或目录: 代码块

#
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [S=3]
RewriteRule ^([^./]+)/$ http://www.santweb.co.uk/$1 [L]
RewriteRule ^([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2 [L]
RewriteRule ^([^./]+)/([^./]+)/([^./]+)/$ http://www.santweb.co.uk/$1/$2/$3 [L]
#

我发现这个,来自:


我认为它在Apache 2.4中非常有用,您可以使用
指令:

RewriteEngine On
<If "%{HTTP:Upgrade} == 'websocket'">
    RewriteRule /nidoran/(.*)           ws://localhost:8080/nidoran/$1 [P,L]
    RewriteRule /kakuna/(.*)           ws://localhost:8081/kakuna/$1 [P,L]
    RewriteRule /porygon/(.*)           ws://localhost:8082/porygon/$1 [P,L]
</If>
重新编写引擎打开
重写规则/nidoran/(*)ws://localhost:8080/nidoran/$1[P,L]
重写规则/kakuna/(*)ws://localhost:8081/kakuna/$1[P,L]
重写规则/porygon/(*)ws://localhost:8082/porygon/$1[P,L]

这正是我需要的,侯赛因!您可以在需要虚拟子域的地方使用Wb变量。这只解决逻辑部分,而不是反向引用部分,因为从技术上讲,
RewriteCond
仍然只适用于第一个
RewriteRule
。最初的问题确实需要回溯。我在我的anwser的最后一句中提到过这一点,@rustyx。尽管如此,我认为许多不需要反向引用的用户会阅读此帖子,并会喜欢基于跳过的解决方案。@Jpsy任何可能跳过的规则都有自己的条件吗?如果是这样,这是否会影响在
S
参数中设置的内容?@JAAulde我想不会。我从来没有尝试过,但文档只讨论跳过重写规则,而不是条件。但是你应该看看新的指令。它们从Apache2.4开始提供,可能会解决您的问题。请看@Jpsy,谢谢!是的,我想使用
,但我现在使用的是Apache2.2。是的,不好玩。应该有人告诉Apache的员工if/else阻塞。谢谢。您可以查看这里列出的4个技巧,