htaccess – 从查询stringredirect到URL

我有以下url:

example.com/?redirect=some-url-encoded 

我需要redirect到查询string中指定的URL( redirect参数)。

我努力了:

 RewriteCond %{QUERY_STRING} redirect=(.+) RewriteRule ^(.*)$ %1 [R=302,L,QSA] 

但是我被redirect到了URL:

 example.com/some-url-encoded?redirect=some-url-decoded 

所以:

  1. 我的url没有解码
  2. 旧的查询string被应用。
  3. url是从example.com开始的

如何正确处理?

  1. 我的url没有解码

QUERY_STRING服务器variables没有被URL解码,mod_rewrite也会对这个replace进行URL编码,所以你很可能以一个双重编码的URL结束? 您可能需要NENOESCAPE )标志。

但是,如果查询string参数中的冒号和斜线(如http:// )是URL编码(即http:%3A%2F%2F ),则这些将传递给已编码的replace,否定它们的正常含义在一个URL中。 尽pipe大多数URL编码函数都会对这些字符进行编码,但是它们并不一定需要在URL参数值中进行编码(尽pipe这可能取决于您的服务器configuration – 如果要更改服务器认为的URL分隔符,但这种情况很less见) 。 所以,编码所有其他字符,除了:/在URL参数值。 例如,而不是:

 example.com/?redirect=https%3A%2F%2Fwww.google.pl%2F 

留下:冒号)和/ (斜杠)字符未编码:

 example.com/?redirect=https://www.google.pl/ 

另一种方法是不使用URL参数,而是在URL的末尾使用附加的PATH_INFO ,因为这应该被自动URL解码。 但是,这取决于AcceptPathInfo指令,您还需要启用AllowEncodedSlashes (在服务器configuration中),但是这带有它自己的安全问题。 查看Apache文档: http : //httpd.apache.org/docs/current/mod/core.html#allowencodedslashes

  1. 旧的查询string被应用。

您明确告诉mod_rewrite应用带有QSA (查询string追加)标志的原始查询string。 但无论如何它会默认这样做。 你需要用Apache 2.4+上的QSD (Query String Discard)标志来清除它,或者附加一个?RewriteRulereplace。

  1. url是从example.com开始的

您需要在URL参数中包含一个绝对URL(即完整的schemehttp:// )(或者在replace中明确硬编码)。 请注意,如果http://中的冒号和/或斜线是URL编码,那么Apache将不会将其视为绝对URL,并且将被视为相对(以当前目录为准),而Apache将以目录前缀为前缀然后尝试使其绝对(因为R标志 – 外部redirect),通过在协议和当前域即前缀。 http://example.com 。 这不仅会彻底破坏redirect,还会暴露内部目录结构。

综合起来,请尝试以下方法:

 RewriteCond %{QUERY_STRING} redirect=(.+) RewriteRule ^ %1? [R=302,L,NE] 

这是假定协议/scheme在查询string参数中传递。 例如。 http://example.com/?redirect=http://www.google.pl/

RewriteRule模式(即。 (.*) )中的加括号的子模式在这里似乎是不必要的。

关于安全的一个字

请注意,允许将任何绝对URL用作此类简单redirect脚本中的目标,这是一个安全风险。 如果黑客发现这一点,那么它很可能被滥用,并被用作redirect链的一部分,指导用户下载恶意软件等。

也可以看看:
https://webmasters.stackexchange.com/questions/99749/301-redirect-script-being-abused-for-what-purpose

你走错了路。 使用RewriteCond / RewriteRule重写path(使用QSA保留查询string)到脚本(PHP或一些CGI,无论你喜欢什么),然后让该脚本体现逻辑和正确性约束,以获得你喜欢的redirect。

这也提供了有用的启用function。 一些想法:

  • 不区分大小写,分隔符 – insentivity(这个东西与thisthing与…)
  • 从数据库中提供这样的redirect
    • 然后可以有一个可靠的Web维护者的前端添加链接,并允许某种生命周期维护。
  • 您甚至可以使用编辑距离来帮助确定需要的文档(请参阅https://en.wikipedia.org/wiki/Levenshtein_distance