我想了解有关的几件事RewriteRule
。
URL 上的工作规则将查询剥离回重定向,例如 URL:
https://www.example.com/application?user=543&AppLink=https://www.example.net/register/reg.aspx?EnquiryID=12345
工作.htaccess
代码:
RewriteCond %{REQUEST_URI} ^/application$
RewriteCond %{QUERY_STRING} .*AppLink=(.*)
RewriteRule ^(.*)$ %1 [R=302,L]
正确结果是重定向 URL:
https://www.example.net/register/reg.aspx?EnquiryID=12345
一切都很好,直到我想在查询链接中引入 URL 编码,例如:
https://www.example.com/application?user=543&AppLink=https%3A%2F%2Fwww.example.net%2Fregister%2Freg.aspx?EnquiryID=12345
首先,编码的引入破坏了工作RewriteRule
,导致 http_host 名称再次出现 - 我不明白为什么会这样:
https://www.example.com/https%3A%2F%2Fwww.example.net%2Fregister%2Freg.aspx?EnquiryID=12345
因此,我试图找出%3A%2F%2F
在将查询作为重定向功能的有效 URL 之前将(例如)“解码”/剥离回冒号和斜线的最佳方法。
我假设,在某种程度上,我需要创建一个“循环”RewriteRule 来整理编码(正则表达式),然后将其重定向到同一个主机,剥离有效的 URL 并将其发送到重定向的主机!
是的,很混乱,而且开销很大。
有人对解决这个问题的最佳方法有什么建议或想法吗?
答案1
...解决这个问题的最佳方法是什么?
这实际上是您的 Web 应用程序(例如 PHP、Python 等)的任务,而不是 Apache(.htaccess
)。
如果这个脚本是“公开的”,那么......这种性质的“重定向”脚本经常被诈骗者滥用(例如),因此您需要将可能的重定向目标列入白名单(并可选择验证发件人)。这可能很难实现,.htaccess
并且可能更适合您的应用程序本身。
https://www.example.com/application?user=543&AppLink=https%3A%2F%2Fwww.domain2.com%2Fregister%2Freg.aspx?EnquiryID=12345
人物:
和/
不需要当它们出现在 URL 的查询字符串部分时,需要进行 URL 编码。但是,如果您要正确地对AppLink
URL 参数值进行 URL 编码,那么您还会对?
and =
(目标 URL 的一部分)进行 % 编码。
首先,编码的引入破坏了有效的 RewriteRule,导致 http_host 名称再次出现 - 我不明白为什么会这样:
服务器QUERY_STRING
变量未经过 % 解码。因此,结果代换字符串是:
https%3A%2F%2Fwww.example.net%2Fregister%2Freg.aspx?EnquiryID=12345
Apache/mod_rewrite 将此视为相对 URL,因为它不是以斜杠或有效方案开头(即https://
)。对于相对 URL,mod_rewrite 使用RewriteBase
当前请求中的方案和主机名(以及目录前缀或指令的值)(默认情况下),以便为外部重定向,因此您看到的是格式错误的重定向。
解决方案
如上所述,我建议在您的应用程序中执行此操作,而不是.htaccess
。但无论如何,要回答您的具体问题,您可以执行类似下面的操作而不是当前的指令。但是,这需要 Apache 2.4+ 和对您的服务器配置的访问权限(因为AllowEncodedSlashes
在目录/上下文中不允许.htaccess
):
以下内容需要放在你的服务器配置(或虚拟主机):
# Allow %2F to be used in the URL-path part of the URL
# Otherwise Apache will trigger a system generated 404 (security feature)
AllowEncodedSlashes On
然后,在.htaccess
:
# Convert URL param value to path-info (via URL rewrite)
# This essentially %-decodes the URL parameter value
RewriteCond %{QUERY_STRING} AppLink=(.+)
RewriteRule ^application$ /application/%1 [QSD]
# Issue redirect using the %-decoded URL-path
RewriteRule ^application/(https?:/)(.+) $1/$2 [R,L]
笔记:
- 如果可能的话,使用以下方法检查 URL 路径会更有效:
RewriteRule
图案而不是使用额外的状况检查REQUEST_URI
服务器变量。 QSD
需要(查询字符串丢弃)标志来丢弃初始AppLink
请求中的(和任何其他)URL 参数。- 第一个 URL 重写被传递到触发实际重定向的下一个指令。
RewriteRule
指令自然地链接在一起,一个指令的输出被用作下一个指令的输入,依此类推。 - URL 路径
RewriteRule
图案匹配的是 % 解码的。(而QUERY_STRING
服务器变量仍然是 % 编码的。)但是,URL 路径中的连续斜杠会缩减为单个斜杠。因此https:/
,https://
在RewriteRule
图案以及在代换。
这还假设您的配置中允许附加路径名信息。如果不允许,您可能需要AcceptPathInfo On
在.htaccess
(或服务器配置)中明确设置。如果没有,那么您还将获得系统生成404.