13

我知道以前有人问过类似的问题,但我还没有找到适合我的情况的任何真正具体的答案。

我有一个在多个环境(本地、开发、生产)上运行的 ExpressionEngine 站点,每个环境都需要不同的 .htaccess 规则:

所有环境

发展

  • 使用 .htpasswd 进行密码保护
  • 强制 HTTPS 协议
  • 使用X-Robots-Tag防止搜索引擎索引

生产

  • 强制 HTTPS 协议
  • 将非 www 子域重定向到 www

当地的

  • 没有独特的规则。

我已经看到了很多关于如何为每个模块设置特定环境的示例。就像RewriteCond %{REQUEST_HOST} ^dev.myurl.commod_rewrite 模块一样,像这样的技巧.htpasswd 要求。

但我真正喜欢的是某种方式来设置全局环境变量,然后在每个环境的 .htaccess 文件中重新使用这些变量。以伪javascript为例,例如:

var local = 'mysite.local';
var development = 'dev.mysite.com';
var production = 'www.mysite.com';

// Global .htaccess rules

if(environment == local){
   // Local environment .htaccess rules
}

if(environment == development){
   // Development environment .htaccess rules
}

if(environment == production){
   //Production envirotnment .htaccess rules
}

这样,所有特定于环境的规则都组合在一起,形成一个非常干净的文件,如果环境发生变化,只需更改一个变量。

我已经看到一些关于更改 Apache 配置文件中的设置的参考,但如果我正在处理 3rd 方主机,这显然不是一个可行的选择。

那么这个天上掉馅饼是一厢情愿,还是可以做到呢?

4

2 回答 2

11

乔恩的回答很好。不幸的是,并非所有网络主机都允许您控制启动 Apache 的 -D 参数。

这是一种在开发和生产上使用单个 htaccess 文件的方法,但只有开发站点密码保护:

# ----------------------------------------------------------------------
# Password protect staging server
# Use one .htaccess file across multiple environments
# (e.g. local, dev, staging, production)
# but only password protect a specific environment.
# ----------------------------------------------------------------------

SetEnvIf Host staging.domain.com passreq
AuthType Basic
AuthName "Password Required"
AuthUserFile /full/path/to/.htpasswd
Require valid-user
Order allow,deny
Allow from all
Deny from env=passreq
Satisfy any
于 2012-10-22T20:20:54.780 回答
8

那么这个天上掉馅饼是一厢情愿,还是可以做到呢?

海事组织,是的。您永远无法根据 ENV 变量或类似的东西获得可预测的规则“范围”。if(something) { do everything in here }apache中不存在任意性。许多指令在某些范围内不起作用,并且在以后,当您需要更改某些东西的工作方式时,您更有可能破坏您拥有的东西,而不是简单地修改它。

最好的方法是根本不使用 htaccess 文件

如果您有权访问 httpd 主服务器配置文件,则应完全避免使用 .htaccess 文件。使用 .htaccess 文件会降低 Apache http 服务器的速度。您可以包含在 .htaccess 文件中的任何指令都最好设置在Directory块中,因为它具有相同的效果和更好的性能。

为本地、开发和生产创建单独的虚拟主机。根据需要打开或关闭它们,无论它们共享什么全局配置,将其存储在其他地方(例如在一个名为 的文件中global.includes),然后Include在所有 3 个虚拟主机中使用该指令。如果您需要将规则应用于特定目录,请使用<Directory>块而不是 htaccess 文件。

如果您宁愿将所有内容都放在 htaccess 文件中,则可以尝试将所有内容都放在<IfDefine>blocks中,这可能是您问题中与伪代码最接近的东西。本质上是这样的:

# Global htaccess rules
RewriteEngine On
RewriteRule ^foo$ /bar [L]

# Only local
<IfDefine LocalInstance>
    RewriteRule ^local/foo /bar [L]
</IfDefine>

# Only dev
<IfDefine DevInstance>
    RewriteRule ^dev/foo /bar [L]
</IfDefine>

# Only production
<IfDefine ProductionInstance>
    RewriteRule ^dev/foo /bar [L]
</IfDefine>

然后,当您启动 apache 时,您需要传入-DLocalInstance-DDevInstance-DProductionInstance作为命令行参数或Define在 vhost 配置中的某处使用指令(只有一个参数)。这不能保证像看起来应该的那样顺利,我之前遇到过无法解释的问题<IfDefine>,特别是如果你想太花哨的话。

于 2012-10-14T22:28:43.170 回答