我今天更新了apache(到2.4.56-1),一堆.htaccess
的重写现在出现了AH 10411错误,与查询中的空格有关。我正在努力寻找一个“合适的”解决方案。
用户单击<a href='FISH%20J12345.6-78919'>clickme</a>
之类的链接-您可以看到链接URL中的空格已被编码为%20
。
相关服务器目录中的.htaccess
文件包含并执行以下相关指令:RewriteRule ^(FISH\s*J[0-9\.]+-?\+?[0-9]+)$ myPage.php?sourceName=$1 [L,QSA]
(In以上我检查的是空格,而不是%20,因为浏览器似乎在符合此规则之前将其转换为空格)。
在我更新Apache之前,这是可行的;现在用户得到一个403错误,我的Apache错误日志得到:AH10411: Rewritten query string contains control characters or spaces
这似乎是一个新的错误,因为谷歌它什么也找不到!
编辑我的页面,例如将空格改为下划线并正确处理它,实际上并不是一个选项,因为设计的目的是支持用户能够直接使用他们关心的对象的名称输入URL。到目前为止,我发现它有点难看的唯一解决方案是,在regexp中分别捕获源名称的两个部分,因此:
RewriteRule ^(FISH)\s*(J[0-9\.]+-?\+?[0-9]+)$ myPage.php?sourceName=$1+$2 [L,QSA]
^ ^ ^^^
(最后我试了1%20$2,结果也很糟糕)。
有没有更好的解决方案?也就是说,当URL中的空格在字符串中时,我应该如何处理它,我想捕获它并将其作为参数传递给底层页面?
2条答案
按热度按时间mpgws1up1#
(最后我试了1%20$2,结果也很糟糕)。
这看起来像是一个错误。在查询字符串中将 space 编码为
%20
应该是有效的。您也可以在查询字符串中将 space 编码为+
(如您的解决方法所示)。在最初的规则中,Apache应该在进行内部重写时对空格进行编码(如
%20
)(因为文本空格在URL中是无效的)。您还可以尝试在原始规则中使用
B
标志。B
标志告诉mod_rewrite在将反向引用应用于 substitution 字符串之前对其进行URL编码。但是,这似乎取决于Apache在查询字符串中将空间编码为+
(与通常的%20
相反)。当然,在Apache的早期版本中,这只会导致Apache将 space 编码为%20
(不是+
),但是,从版本2.4.26开始,Apache引入了一个新的标志BNP
(backrefnoplus
),它显式地通知Apache not 使用+
,因此您可能认为默认情况下,它将使用+
。(不幸的是,我现在不能自己测试它。)例如:
(次要的一点......当在regex字符类中使用时,不需要反斜杠转义文字点。我还将数字范围缩减为简写
\d
。)-
和+
吗?看起来应该是其中之一(或者什么都没有)?例如[-+]?
。有没有更好的解决方案?也就是说,当URL中的空格在字符串中时,我应该如何处理它,我想捕获它并将其作为参数传递给底层页面?
不太会(尽管你的解决方案并不完全正确--见下文)。在你的特定示例中,它只包含 * 空格 *,你不需要做任何事情。你总是可以使用
B
标志(如上所述)。如果存在其他特殊字符,则 * 需要 * 使用B
标志,例如&
(查询字符串中的特殊字符),否则该字符串不会被URL编码(实际上导致URL参数值被截断)。您的解决方案存在一个问题,即您允许请求中包含0个(即“none”)或更多的 * space *,并在结果URL参数中强制使用单个 space。这与原始指令不同,原始指令将保留原始请求中的空格(或缺少空格)。
初始请求中是否可以包含0个或更多空格?
如果是的话,并且这些需要被保留,那么对你需要的任意多的“空格”重复这个规则可能会更容易,你可以实现一个搜索/替换,但是那可能是矫枉过正。
(In以上我检查的是空格,而不是%20,因为浏览器似乎在符合此规则之前将其转换为空格)。
RewriteRule
* 模式 * 匹配的URL路径首先进行URL解码(%解码),这就是为什么您需要与文字 * 空格 * 而不是%20
匹配。这与“浏览器”无关。URL路径中的任何文字 * 空格 * 在离开浏览器/用户代理的HTTP请求中必须URL编码为%20
,否则将It“这根本是无效的。guicsvcw2#
这是最近的一次。