1

我正在使用 Apache RewriteMap 永久重定向 60 个左右的 url。在一个开发环境中,以下配置可以完美运行,而在另一个开发环境中它根本不起作用。最值得注意的是,最后一个RewriteCond从未通过,不幸的是我尝试的日志记录选项没有帮助。使用LogLevel debug rewrite:trace8,我可以看到RewriteCond地图正在接收预期的输入之前,但地图仍然没有返回匹配项:

[Thu Apr 19 19:35:19.109789 2018] [rewrite:trace4] [pid 11188] mod_rewrite.c(470): [client 127.0.0.1:62369] 127.0.0.1 - - [server.dev/sid#7f7719da0d50][rid#7f7719fc8000/initial] [perdir /html/path/] RewriteCond: input='/help_center/help_center.php?' pattern='^/?(.*[^\\?])\\??/?$' => matched
[Thu Apr 19 19:35:19.109793 2018] [rewrite:trace4] [pid 11188] mod_rewrite.c(470): [client 127.0.0.1:62369] 127.0.0.1 - - [server.dev/sid#7f7719da0d50][rid#7f7719fc8000/initial] [perdir /html/path/] RewriteCond: input='NOTFOUND' pattern='!NOTFOUND' [NC] => not-matched

出于调试目的,我简化了将常量键传递给映射的事情,但映射仍然不返回替代值。我还尝试过简化映射文件,添加它可以接收的所有可能的键变体(有和没有前导/尾随斜杠和?)。我尝试重命名地图文件和扩展名,重命名地图本身,将地图文件移到公共目录之外,所有这些都没有改变结果。地图文件和它所在的目录一样是可读的,Apache 使用配置启动时没有错误,是的,我在测试配置更改时一直在重新启动它。

还有什么可以尝试的?两个系统都运行 CentOS 7、Apache 2.4,一个可以工作,一个不能。下面的配置

Apache 服务器级配置声明映射

RewriteMap help_center txt:/path/to/rewritemap/help_center.map

.htaccess

RewriteEngine on
RewriteCond %{REQUEST_URI}                  !(\.(js|css|less|png|swf|flv|jpg|svg|ico))$
RewriteCond %{REQUEST_URI}?%{QUERY_STRING}  ^/?(.*[^\?])\??/?$
RewriteCond ${help_center:%1|NOTFOUND}      !NOTFOUND [NC]
RewriteRule ^.*$                            /${help_center:%1}/ [QSD,L,NC,R=301]

help_center.map 的缩略内容

help_center/help_center.php           help-center
help_center/help_center.php?1_7_q-1   help-center/article/authorized-dealer
pages/appliance_installation          help-center/article/installation-services

更新

经过6个小时的调试,我终于可以让RewriteMap匹配了。通过将RewriteMap指令移动到<VirtualHost _default_:443>范围内/etc/conf.d/ssl.conf,url 正在按预期重写。

为什么会这样?

除了虚拟主机之外,这两个环境之间的配置非常相似。两种环境都运行 SSL 并将所有请求重定向到 SSL 站点。工作的环境配置为没有基于名称的虚拟主机配置(即服务器的一个站点),而不起作用的环境是运行基于名称的虚拟主机。我有一个与此相关的假设:

虽然我希望 root 指令适用于默认站点和所有虚拟站点(包括 SSL),但也许该RewriteMap指令必须是虚拟主机范围,才能被虚拟主机引用。不确定这是否有意义,但我找不到任何文件来澄清。测试后,关闭NameVirtualHost没有任何变化:/

相关:似乎引用不存在的 RewriteMap 不会记录错误。也许它在我打开调试日志记录时被埋没了,但是是否有用于记录 RewriteMap 引用错误的配置?这将有助于更快地缩小我的调试范围。

最后,为了检查已解析的 Apache 配置,请从命令行运行:httpd -DDUMP_CONFIG -k start或在 vi 中查看httpd -DDUMP_CONFIG -k start | vi -。我能够使用它来确认我的 RewriteMap 指令正在加载,尽管它仍然不匹配。

4

1 回答 1

1

我不完全确定这应该有资格作为答案,但我认为这就是使它起作用的原因:删除QSD参数并附加 a?以手动丢弃它。进行此更改是因为我们有一个运行 2.2 的服务器会完全出错(而不是不匹配),并且似乎副作用是我们的 2.4 服务器现在正在匹配。我确定不是 Voodoo,但不幸的是我无法自信地解释它。

## QSD not available in apache 2.2, add a ? to the end of the rewrite to discard
RewriteRule ^.*$   /${help_center:%1}/? [L,NC,R=301]
于 2018-07-24T16:19:16.500 回答