我正在使用 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 指令正在加载,尽管它仍然不匹配。