我有以下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
所以:
如何正确处理?
- 我的url没有解码
QUERY_STRING服务器variables没有被URL解码,mod_rewrite也会对这个replace进行URL编码,所以你很可能以一个双重编码的URL结束? 您可能需要NE ( NOESCAPE )标志。
但是,如果查询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
- 旧的查询string被应用。
您明确告诉mod_rewrite应用带有QSA (查询string追加)标志的原始查询string。 但无论如何它会默认这样做。 你需要用Apache 2.4+上的QSD (Query String Discard)标志来清除它,或者附加一个? 到RewriteRulereplace。
- 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链的一部分,指导用户下载恶意软件等。
你走错了路。 使用RewriteCond / RewriteRule重写path(使用QSA保留查询string)到脚本(PHP或一些CGI,无论你喜欢什么),然后让该脚本体现逻辑和正确性约束,以获得你喜欢的redirect。
这也提供了有用的启用function。 一些想法: