【问题标题】:How Can I Have A Conditional .htaccess Block?我怎样才能有条件的 .htaccess 块?
【发布时间】:2010-10-18 16:51:20
【问题描述】:

这是一个您以前可能遇到过的 Apache 问题。我想要一个可以部署到我的工作站、登台服务器和生产服务器的源程序包,但它可以根据 URL 加载不同的 .htaccess 设置。

请注意,我在调用 IfModule 时使用了 kludge,但这不适用于我们的新生产服务器,因为它与我的登台服务器共享所有相同的模块。

注意,我需要将 SetEnv 与这些重写捆绑在一起。目前如果你使用 RewriteCond,它只与下面的 RewriteRule 相关联,而不是下面的 SetEnv。

【问题讨论】:

    标签: apache .htaccess apache2


    【解决方案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?我的意思是,在普通的编程语言和标记中,你有某种开始/停止块,无论是花括号。但不在这里
    • 还有,RewriteBase / 重要吗?
    • 这种方法的问题是它只适用于RewriteRule,尝试将它也用于SetEnv或php_value,它不起作用。这就是我使用 IfModule 组件的原因。
    【解决方案2】:

    不使用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,因为我的 prod 服务器 100% 由我控制,我可以弄乱 /etc/sysconfig/httpd OPTION 参数并将其设为 OPTIONS="-D prod"。在共享的登台服务器上,我必须使用 IfDefine !prod 然后在它下面堆叠一个 IfModule expires_module。在我的工作站上,我必须使用 IfDefine !prod 和 IfModule !expires_module。这给了我一个 .htaccess 文件,该文件可用于开发、登台/测试和生产。
    • 有点混乱,让我觉得可以在 ifdefine 上使用简单的环境变量
    • RewriteCond 很难理解。使用定义有点笨拙。我认为更好的解决方案是对 URL 或 IP 地址使用条件。当我弄清楚如何做到这一点时,我将发布作为答案。
    【解决方案3】:

    在 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 的试验,查看您需要编辑的文件。

    【讨论】:

      【解决方案4】:

      我尝试了 IfDefine 方法,但它不起作用,即使我传递给 Apache 启动的定义变量肯定显示在 APACHE_ARGUMENTS 行的 phpinfo() 中。

      我尝试了另一种方法,效果很好。在您的 .htaccess 文件中,您需要以下内容:

      # Is the domain local (i wanted to check two names)? <If "%{SERVER_NAME} != 'localhost' && %{SERVER_NAME} != 'myproject.localhost'"> # I wanted to password protect the production server only AuthType Basic AuthName "Restricted area" AuthUserFile /app/.htpasswd require valid-user </If>

      我使用的是 Apache 2.4。可能不适用于早期版本。

      【讨论】:

        猜你喜欢
        • 2020-10-26
        • 2012-12-26
        • 1970-01-01
        • 2011-02-28
        • 1970-01-01
        • 2020-06-07
        • 2022-01-12
        • 2015-03-13
        • 1970-01-01
        相关资源
        最近更新 更多