如何在 .htaccess 文件中添加条件限制?

18

这是一个你可能遇到过的Apache问题。我希望有一个源代码包,可以部署到我的工作站、预备服务器和生产服务器上,但根据URL加载不同的.htaccess设置。

请注意,我曾经使用IfModule调用来解决这个问题,但这在我们的新生产服务器上行不通,因为它与我的预备服务器共享了所有相同的模块。

请注意,我需要将SetEnv与这些重写捆绑在一起。目前,如果使用RewriteCond,则仅适用于以下的RewriteRule,而不适用于下面的SetEnv。

4个回答

15

不要使用SetEnv,而是使用RewriteRule本身的环境变量设置功能:

RewriteCond %{HTTP_HOST} =foo.com
RewriteRule ^ - [E=VARNAME:foo]

RewriteCond %{HTTP_HOST} =bar.com
RewriteRule ^ - [E=VARNAME:bar]

虽然我更喜欢通过在httpd进程启动时传递标志并使用IfDefine块查找它们来完成这种操作。

<IfDefine FOO>
SetEnv VARNAME foo
</IfDefine>

<IfDefine BAR>
SetEnv VARNAME bar
</IfDefine>

需要注意的是,在Apache中的php_value指令不能在第一个示例中调用,只能使用环境变量。在第二个示例中,这是最好的选择,因为您可以直接定义您的服务器。但是,这仅适用于您控制环境的情况。如果您在共享主机上,则无法控制传递参数到httpd进程的方式。因此,您需要使用<IfDefine !FOO>来寻找其反义词。 - Volomike
1
我发现我可以使用IfDefine,因为我的生产服务器完全由我控制,我可以操纵/etc/sysconfig/httpd OPTION参数并使其OPTIONS="-D prod"。在共享的staging服务器上,我必须使用IfDefine !prod,然后在其下面堆叠一个IfModule expires_module。在我的工作站上,我必须使用IfDefine !prod,然后是IfModule !expires_module。这给了我一个.htaccess文件,在开发、staging/test和生产中都能正常工作。 - Volomike
有些令人困惑,让我以为简单的环境变量可以用于 ifdefine。 - Dan
RewriteCond 很难理解。使用定义有点笨拙。我认为更好的解决方案是在 URL 或 IP 地址上使用条件语句。当我弄清楚如何做到这一点时,我会发布一个答案。 - David Spector

6
在Ubuntu Linux上,IfDefine的变量是在中设置的。
/etc/apache2/envvars

它被称为APACHE_ARGUMENTS。因此,在该文件的底部,我必须添加:

export APACHE_ARGUMENTS="-D dev"

然后使用以下命令重新启动服务器:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start

在其他系统上:

然而,有一篇关于这个主题的Debian文章,在这里讨论了这个问题here。 在那个例子中,要编辑的文件是/etc/default/apache2,变量被称为APACHE_DEFINES

同样,在某些系统上,它是一个名为OPTIONS 的变量,设置在/etc/sysconfig/httpd中。

因此,你真正需要做的是查找apache2ctl文件中的起始部分。所以,首先通过执行whereis apache2ctl命令来找到该脚本所在的位置,将其输出并查找带有apache2指令的启动部分,并查看传递的变量是OPTIONSAPACHE_ARGUMENTSAPACHE_DEFINES或其他内容。然后,通过试验/etc/sysconfig/httpd/etc/default/apache2/etc/apache2/envvars来确定需要编辑的文件。


2

我尝试了IfDefine方法,但它没有起作用,即使我在Apache启动时传递的定义变量在APACHE_ARGUMENTS行上在phpinfo()中确实显示出来。

我尝试了另一种方法,它完美地工作了。在你的.htaccess文件中,你需要像这样写:

# 判断域名是否为本地(我想检查两个名称)? <If "%{SERVER_NAME} != 'localhost' && %{SERVER_NAME} != 'myproject.localhost'"> # 我只想保护生产服务器 AuthType Basic AuthName "Restricted area" AuthUserFile /app/.htpasswd require valid-user </If>

我正在使用Apache 2.4。可能不适用于早期版本。


1

这是一个简单的例子,足以让您进行修改以满足您的要求:

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteBase /

    RewriteCond %{HTTP_HOST} !^localhost
    RewriteCond %{HTTP_HOST} !^www\.
    RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

这个是否是串行工作的,我可以在它下面附加另一个RewriteCond和更多的RewriteRule条目,它只会应用于前一个RewriteCond吗?我的意思是,在正常的编程语言和标记中,你有一些开始/停止块,无论是花括号。但这里没有。 - Volomike
此外,RewriteBase / 重要吗? - Volomike
1
这种方法的问题在于它只适用于RewriteRule,而尝试将其用于SetEnv或php_value时则会失败。这就是为什么我使用IfModule的诡计。 - Volomike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接