URL 在 htaccess 重写规则之前解码
URL Decoded Prior to htaccess Rewrite Rule
我在 .htaccess 中有以下重写规则:-
RewriteRule ^.*/-y.* /handleurl.php [L]
其目的是根据url中的值显示合适的页面,例如:
example.com/books/BookA/-y?act=x
会显示bookA页
保存书名的变量被编码为...
example.com/books/Book B/-y?act=x
变为 example.com/books/book+B/-y?act=x
...很好(在 handleurl.php
中解码)
但是如果这本书叫 Book A/B
我有...
example.com/books/Book A/B/-y?act=x
变为 example.com/books/Book+A%2FB/-y?act=x
htaccess 似乎在重写规则之前对此进行了解码,因此重写规则在 /
.
所描述的 URL 中看到了太多元素
有什么方法可以让重写规则按预期忽略编码的 /
吗?
之前看到过类似问题的回复,不过我只需要忽略/
,其他编码字符都不需要。
It appears that htaccess decodes this before the rewrite rule, so the rewrite rule sees too many elements in the URL delineated by the /
这不是问题所在。不管URL-路径/books/Book+A%2FB/-y
是否解码在这里都没有区别*1。两者都将匹配 RewriteRule
模式 .
中的(相当慷慨的)正则表达式 ^.*/-y.*
(*1 但是,是的,URL-路径与 RewriteRule
模式匹配 被 URL 解码,即 %-解码。)
问题很可能是 Apache(默认情况下)拒绝 - 使用 404 - 任何包含 % 编码斜杠的 URL 即。 %2F
(或反斜杠 %5C
)在 URL 的 URL 路径部分。这是一项 安全功能 ,否则“可能会允许不安全的路径”(source)。
但是,这可以用 AllowEncodedSlashes
指令覆盖。但是该指令只能在 server 或 virtualhost 上下文中使用。它不能在 .htaccess
.
中使用
您要么需要设置 AllowEncodedSlashes On
以允许编码的斜杠,它也像其他字符一样被解码。或者设置 AllowEncodedSlashes NoDecode
以允许编码的斜杠,但不要对其进行解码 - 这是首选并且可能是您所期望的。
旁白#1:
RewriteRule ^.*/-y.* /handleurl.php [L]
正则表达式 ^.*/-y.*
非常通用,可能太通用了。这与简单的 /-y
相同。 -y
之后的 .*
是什么意思?从你的例子 URLs 看起来 -y
总是在 URL-path 的末尾,所以这可以被锚定,例如。 /-y$
。如果您需要匹配的 URL 始终以 /books/
开头,那么也许这也应该包含在正则表达式中?
旁白#2:
...the book name is encoded such that ...
example.com/books/Book B/-y?act=x
becomes example.com/books/book+B/-y?act=x
... which is fine (it's decoded in handleurl.php)
这不是严格意义上的“URL 编码”,您已经转换 space 为+
在 URL 路径中。仅在查询字符串中使用时,+
是 space 的有效“URL 编码”。 URL 路径中的 +
是文字 +
(搜索引擎也会看到)。在 URL 路径中,space 将被 URL 编码为 %20
。 (您可能使用了错误的 PHP 编码函数,例如 urlencode()
而不是 rawurlencode()
?)
当然,您可以自由地 convert/encode URL,但是您希望创建更具可读性的 URL - 只要它是有效的。
重写规则从来都不是问题。我认为这是 Apache 不喜欢编码的 '/' 以及下游 url 处理程序在识别单个 url 元素时使用 '/' 作为分隔符的事实。我必须解决:1)我是否要在构成 freindly url 的元素的变量中允许“/”,以及 2)如果是这样,如何在不扰乱 Apache 的情况下传递它以及如何随后剖析url。也许为了 URL 的好处,我会将“/”转换为“~”,然后在后续显示之前转换回“/”。谢谢怀特先生。
我在 .htaccess 中有以下重写规则:-
RewriteRule ^.*/-y.* /handleurl.php [L]
其目的是根据url中的值显示合适的页面,例如:
example.com/books/BookA/-y?act=x
会显示bookA页
保存书名的变量被编码为...
example.com/books/Book B/-y?act=x
变为 example.com/books/book+B/-y?act=x
...很好(在 handleurl.php
中解码)
但是如果这本书叫 Book A/B
我有...
example.com/books/Book A/B/-y?act=x
变为 example.com/books/Book+A%2FB/-y?act=x
htaccess 似乎在重写规则之前对此进行了解码,因此重写规则在 /
.
有什么方法可以让重写规则按预期忽略编码的 /
吗?
之前看到过类似问题的回复,不过我只需要忽略/
,其他编码字符都不需要。
It appears that htaccess decodes this before the rewrite rule, so the rewrite rule sees too many elements in the URL delineated by the
/
这不是问题所在。不管URL-路径/books/Book+A%2FB/-y
是否解码在这里都没有区别*1。两者都将匹配 RewriteRule
模式 .
^.*/-y.*
(*1 但是,是的,URL-路径与 RewriteRule
模式匹配 被 URL 解码,即 %-解码。)
问题很可能是 Apache(默认情况下)拒绝 - 使用 404 - 任何包含 % 编码斜杠的 URL 即。 %2F
(或反斜杠 %5C
)在 URL 的 URL 路径部分。这是一项 安全功能 ,否则“可能会允许不安全的路径”(source)。
但是,这可以用 AllowEncodedSlashes
指令覆盖。但是该指令只能在 server 或 virtualhost 上下文中使用。它不能在 .htaccess
.
您要么需要设置 AllowEncodedSlashes On
以允许编码的斜杠,它也像其他字符一样被解码。或者设置 AllowEncodedSlashes NoDecode
以允许编码的斜杠,但不要对其进行解码 - 这是首选并且可能是您所期望的。
旁白#1:
RewriteRule ^.*/-y.* /handleurl.php [L]
正则表达式 ^.*/-y.*
非常通用,可能太通用了。这与简单的 /-y
相同。 -y
之后的 .*
是什么意思?从你的例子 URLs 看起来 -y
总是在 URL-path 的末尾,所以这可以被锚定,例如。 /-y$
。如果您需要匹配的 URL 始终以 /books/
开头,那么也许这也应该包含在正则表达式中?
旁白#2:
...the book name is encoded such that ...
example.com/books/Book B/-y?act=x
becomesexample.com/books/book+B/-y?act=x
... which is fine (it's decoded in handleurl.php)
这不是严格意义上的“URL 编码”,您已经转换 space 为+
在 URL 路径中。仅在查询字符串中使用时,+
是 space 的有效“URL 编码”。 URL 路径中的 +
是文字 +
(搜索引擎也会看到)。在 URL 路径中,space 将被 URL 编码为 %20
。 (您可能使用了错误的 PHP 编码函数,例如 urlencode()
而不是 rawurlencode()
?)
当然,您可以自由地 convert/encode URL,但是您希望创建更具可读性的 URL - 只要它是有效的。
重写规则从来都不是问题。我认为这是 Apache 不喜欢编码的 '/' 以及下游 url 处理程序在识别单个 url 元素时使用 '/' 作为分隔符的事实。我必须解决:1)我是否要在构成 freindly url 的元素的变量中允许“/”,以及 2)如果是这样,如何在不扰乱 Apache 的情况下传递它以及如何随后剖析url。也许为了 URL 的好处,我会将“/”转换为“~”,然后在后续显示之前转换回“/”。谢谢怀特先生。