Apache RewriteMap 中的 URL 包含空格,无法正常工作

Apache RewriteMap 中的 URL 包含空格,无法正常工作

我实际上RewriteMap在 vhost 中使用了一条指令来重定向 800 个 URL 列表。它运行良好:

RewriteEngine On
RewriteMap redirects dbm=db:/data/apps/project/current/configuration/etc/httpd/conf/redirects.db
RewriteCond ${redirects:$1} !=""
RewriteRule ^(.*)$ ${redirects:$1} [redirect=permanent,last]

我使用redirect.txt包含映射的文件。然后将其转换为数据库文件:

httxt2dbm -f db -i /data/apps/project/current/configuration/etc/httpd/conf/redirects.txt -o /data/apps/project/current/configuration/etc/httpd/conf/redirects.db

例如对于这种 URL,是可以的:

/associations/old_index.php /

但是当 URL 包含空格时它不起作用:(我猜其他特殊字符也是一样的)

/Universités%20direct   /

这个案子该如何处理?

答案1

一种解决方法可能是在内部重写包含空间改为连字符(将空格替换为连字符),然后将带连字符的 URL 包含在重写映射中。

如果您只有一些 URL 在 URL 内包含单个空格,那么您可以在现有指令之前使用类似以下指令:

RewriteRule ^(.+)\s(.+)$ $1-$2

然后在重写映射中使用以下内容:

/Universités-direct /

更新:如果您的 URL 包含两个空格(例如/the force awakens),并且有些 URL 包含一个空格,那么您可以添加一条附加规则:

RewriteRule ^(.+)\s(.+)\s(.+)$ $1-$2
RewriteRule ^(.+)\s(.+)$ $1-$2

这些规则确实假设您的 URL 不以空格结尾。并且任何 URL 都不能有多个连续的空格。

如果有三个空格,则在上述规则之前添加另一条规则......

RewriteRule ^(.+)\s(.+)\s(.+)\s(.+)$ $1-$2

我倾向于使用多个(简单)规则来实现这一点,而不是通用的“在单个规则中转换所有内容”,除非您特别需要。通用规则将递归运行,将多个空格缩减为单个字符。您还可能需要其他标志(即DPI)来防止 Apache 中已知的重写错误。

答案2

您可以使用第二个重写映射,内部函数“escape”将空格转换为%20:

RewriteMap ec int:escape

RewriteMap redirects dbm=db:/data/apps/project/current/configuration/etc/httpd/conf/redirects.db

RewriteCond ${redirects:${ec:$1}} !=""

RewriteRule ^(.*)$ ${redirects:${ec:$1}} [redirect=permanent,last]

然后在您自己的重写映射数据库中您可以拥有:

/Universités-direct%20/

这样就应该匹配了。

答案3

您可以通过从 %{THE_REQUEST} 变量中提取编码的 URI 并使用它来进行查找来解决这个问题。当然,您需要将编码的 URI 放入映射中。如下所示:

重写引擎开启
RewriteMap 重定向 dbm=db:/data/apps/project/current/configuration/etc/httpd/conf/redirects.db
RewriteCond %{THE_REQUEST} "\w+ ([^ ]+)"
重写规则 ^-[E=MYVAR:%1]

重写条件 ${redirects:%{ENV:MYVAR}} !=""
重写规则 ^ ${redirects:%{ENV:MYVAR}} [redirect=permanent,last] [B]

不过,我只用基于文本的地图而不是数据库地图进行了测试。如果您必须处理带有查询字符串的 URL,则可能需要进行修改。

相关内容