.htaccess 被忽略,特定于 EC2 - 不是通常的嫌疑人

.htaccess 被忽略,特定于 EC2 - 不是通常的嫌疑人

我运行 8-10 个基于 EC2 的 Web 服务器,因此我的经验非常丰富,但仅限于 CentOS;特别是 Amazon 的发行版。我使用 yum 安装 Apache,因此获取 Amazon 的默认 Apache 编译。

我想使用 mod_rewrite 实现从非 www(裸/根)域到 www.domain.com 的规范重定向以进行 SEO,但我的 .htaccess 文件一直被忽略。

我的故障排除步骤(如下所述)使我相信这是亚马逊构建的 Apache 所特有的问题。

测试用例

  1. 启动 EC2 实例,例如Amazon Linux AMI 2013.03.1
  2. SSH 到服务器
  3. 运行以下命令:

    • $ sudo yum install httpd
    • $ sudo apachectl start
    • $ sudo vi /etc/httpd/conf/httpd.conf
    • $ sudo apachectl restart
    • $ sudo vi /var/www/html/.htaccess

在 httpd.conf 中,我在 DOCROOT 部分/范围中进行了以下内容更改:

AllowOverride All

在.htaccess中,添加:

(编辑,我RewriteEngine On后来添加)

RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^/(.*) http://www.domain.com/$1 [R=301,L]

.htaccess 上的权限是正确的,AFAI 可以判断:

$ ls -al /var/www/html/.htaccess -rwxrwxr-x 1 git apache 142 Jun 18 22:58 /var/www/html/.htaccess

其他信息:

$ httpd -v
Server version: Apache/2.2.24 (Unix)
Server built:   May 20 2013 21:12:45

$ httpd -M
Loaded Modules:
 core_module (static)
     ...
 rewrite_module (shared)
     ...
 version_module (shared)
Syntax OK

预期行为

$ curl -I domain.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 19 Jun 2013 12:36:22 GMT
Server: Apache/2.2.24 (Amazon)
Location: http://www.domain.com/
Connection: close
Content-Type: text/html; charset=UTF-8

实际行为

$ curl -I domain.com
HTTP/1.1 200 OK
Date: Wed, 19 Jun 2013 12:34:10 GMT
Server: Apache/2.2.24 (Amazon)
Connection: close
Content-Type: text/html; charset=UTF-8

故障排除步骤

在.htaccess中,添加:

BLAH BLAH BLAH ERROR
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^/(.*) http://www.domain.com/$1 [R=301,L]

我的服务器抛出了错误 500,所以我知道 .htaccess 文件已被处理。

正如预期的那样,它创建了一个错误日志条目: [Wed Jun 19 02:24:19 2013] [alert] [client XXX.XXX.XXX.XXX] /var/www/html/.htaccess: Invalid command 'BLAH BLAH BLAH ERROR', perhaps misspelled or defined by a module not included in the server configuration


由于我在服务器上拥有 root 访问权限,因此我尝试将重写规则直接移至 httpd.conf 文件。这有效。这告诉我们有几件重要的事情正在发挥作用。

$ curl -I domain.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 19 Jun 2013 12:36:22 GMT
Server: Apache/2.2.24 (Amazon)
Location: http://www.domain.com/
Connection: close
Content-Type: text/html; charset=UTF-8

然而,它无法在 .htaccess 文件中工作,这让我很困扰。而且我还有其他用例需要它在 .htaccess 中工作(例如具有命名虚拟主机的 EC2 实例)。

预先感谢您的帮助。

答案1

您可以将 RewriteRules 放在服务器配置中,也可以放在 .htaccess 中。但是,它们之间存在差异,这意味着在服务器配置中有效的规则不一定在 .htaccess 上下文中有效,反之亦然。.htaccess 文件(和目录上下文)中的 RewriteRules 与相对 URL 匹配,因此以 / 开头的规则永远不会被匹配。启用 rewritelog 后您就会看到结果。

因此假设 docroot 是 /var/www 并且你请求http://myserver.com/foo/bar.html

服务器配置中的重写规则将与 /foo/bar.html 进行匹配

上下文中的重写规则或 /var/www/foo 中的 .htaccess 文件中的重写规则将仅与 bar.html 匹配。因此,如果它以 / 开头,则永远不会匹配。

意识到这一点很重要,这也是我通常认为在 .htaccess 文件中使用重写规则是个坏主意的原因之一。我通常强烈建议不要在 .htaccess 文件中使用重写规则(如果可以避免的话)(并且您可以访问 httpd.conf,因此您可以这样做)。.htaccess 文件中的重写规则通常会导致难以诊断的行为,并且会严重影响性能。

另请参阅 apache 文档: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

“在目录和 htaccess 上下文中,模式最初将与文件系统路径进行匹配,然后删除引导服务器到当前 RewriteRule 的前缀(例如“app1/index.html”或“index.html”,具体取决于指令的定义位置)。”

相关内容