我是否需要在 RewriteCond 中转义斜杠“/”?
目前我在.htaccess中写了以下规则:
RewriteCond %{QUERY_STRING} rp=/knowledgebase/
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]
但是,这仅适用于https://www.datanumen.com/fi/customer/index.php?rp=/knowledgebase/7/How-to-order-the-full-version-of-DataNumen-Access之类的 URL -Repair.html&language=swedish,但不适用于https://www.datanumen.com/fi/customer/index.php?rp=%2Fknowledgebase%2F7%2FHow-to-order-the-full-version-之类的 URL of-DataNumen-Access-Repair.html&language=swedish
所以,我必须修改规则,如下所示:
RewriteCond %{QUERY_STRING} rp=/knowledgebase/ [OR]
RewriteCond %{QUERY_STRING} rp=%2Fknowledgebase%2F
RewriteRule ^index\.php$ https://www.datanumen.com/knowledgebase/ [QSD,R=301,L,NC]
但是我检查了https://serverfault.com/a/968916/280923并说“不需要转义斜杠(/) ”。所以我很困惑。
如果我需要考虑所有情况,即'/'的转义版本和非转义版本,那么应该总共有4种组合,我应该将它们全部添加为RewriteCond:
rp=/knowledgebase/
rp=%2Fknowledgebase%2F
rp=%2Fknowledgebase/
rp=/knowledgebase%2F
通过“转义斜杠”,您的真正意思是“我应该匹配 URL 编码的斜杠吗?”。这完全取决于向您的服务器发出的 HTTP 请求。
链接的问题/答案与当前问题无关。该问题是处理 Apache 指令/正则表达式中的反斜杠转义,而不是您在此处处理的 URL 编码(或 % 编码)URL。这是用于不同目的的两种非常不同类型的“转义”方法。
您正在处理的是 % 编码的 URL。URL 在 HTTP 请求中的显示方式。URL 的不同部分(特别是“路径”和“查询字符串”)具有不同的编码要求。是否需要对特定字符进行 % 编码取决于它在该上下文中是否具有特殊含义。
正如RFC3986中定义的那样,斜杠 (
/
) 并不严格需要在 URL 的查询字符串部分进行 % 编码。但是,URL 编码函数(例如 PHP 和 JavaScript)通常会对该字符进行 %-encode。(我认为这在很大程度上是历史性的,因为据报道一些旧的实现没有正确处理未编码的斜线 - 参考RFC3986。)但是,无论一个字符是否需要进行 URL 编码(以否定其特殊含义),任何字符都可以进行 % 编码,这应该与文字(未编码)字符一样对待。
您是否需要匹配
/
(解码)或%2F
(编码)取决于该字符是否在请求中进行了 % 编码。您的问题是
QUERY_STRING
server 变量没有 %-decoded,这与RewriteRule
pattern匹配的 URL-path 不同。但是......你需要检查 %-decoded
/
和 % -encoded%2F
吗?大概您始终只链接到一个或另一个(规范)URL。因此,对非规范 URL 的任何请求都必须由第三方手动输入或错误链接。您是否收到对两者的请求?不重定向非规范 URL 的后果是什么?否则,是的,您需要检查两者(以及可能的所有变体/案例)。尽管这可能只是
/knowledgebase/
或%2Fknowledgebase%2F
。但请注意,它可能是%2F
(大写)或%2f
(小写)。大写只是一个约定。必须检查混合编码,例如%2Fknowledgebase/
应该非常罕见。但这也与%2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f
. 您是否需要处理所有这些变化取决于获得此类请求的可能性以及规则不匹配的严重性。因此,要同时匹配
/knowledgebase/
和%2Fknowledgebase%2F
(不区分大小写),您可以使用以下内容:您可以避免使用字符类
[Ff]
并使用NC
标志来使整个比较不区分大小写。例如:在 Apache 2.4 上,您可以
unescape()
在 Apache 表达式中使用该函数与指令在进行比较之前RewriteCond
对 URL 进行解码。QUERY_STRING
但是,这并不能真正帮助您,因为它不会 %-decode 斜杠,即。%2F
或%2f
根据请求保留(但任何其他字符都被 % 解码)。例如:这将允许您匹配
rp=%2f%6b%6e%6f%77%6c%65%64%67%65%62%61%73%65%2f
.或者,如果您不希望查询字符串中有任何 URL 编码字符,那么您可以简单地阻止任何发送任何请求的请求!例如,以下内容需要放在配置的顶部: