带有文字问号的htaccess RewriteRule(不是查询字符串)

时间:2018-09-05 14:58:05

标签: .htaccess mod-rewrite url-rewriting

我需要能够匹配问号,因为存在翻译后的文本编码错误,并且部分URL最终被硬编码并带有问号。这是我需要重写的URL示例:

https://example.com/Documentation/Product????/index.html

这是我当前的重写规则。当“产品”后面的字符不是问号时,它起作用,但是当它们是问号时,该规则不适用。

RewriteRule "^Documentation/Product[^/]+/(.*)$" "https://s3.amazonaws.com/company-documentation/Help/Product/$1" [L,NC]

在该规则中,我如何确保问号也被视为字符?我不能指望URL中只会出现问号,而不是原始的非英语字符,因此我希望上面的规则能够同时匹配问号和其他任何字符。

我发现这个主题似乎很相关,但是标志并没有帮助,答案也没有解释如何克服“ Aside”中提到的问题。 https://webmasters.stackexchange.com/questions/107259/url-path-with-encoded-question-mark-results-in-incorrect-redirect-when-copied-to

1 个答案:

答案 0 :(得分:1)

https://example.com/Documentation/Product????/index.html

您说的是“不是查询字符串”,但实际上就是这样。这就是为什么您无法将其与RewriteRule 模式相匹配的原因。上面的URL分为以下部分:

  • URL路径:/Documentation/Product(与RewriteRule 模式匹配)
  • 查询字符串:???/index.html(注释3 ?-第一个开始查询字符串)

要匹配查询字符串,您将需要一个附加的RewriteCond指令来检查QUERY_STRING服务器变量。

例如,要匹配上述URL,您需要执行以下操作:

RewriteCond %{QUERY_STRING} ^\?*/index\.html
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/index.html [NC,R,L]

这将匹配查询字符串开头的任意数量的错误?

我添加了Rredirect)标志。您的指令(不带R标志)无论如何都会触发外部重定向(因为您在 substitution 中指定了绝对URL),但在此明确表示要好得多。这也是临时的(302)重定向。如果这应该是永久性的(301),则将其更改为R=301,但是只有在您确认它可以正常工作之后(浏览器将301缓存在硬盘上,这样才能使测试出现问题)。


更新:

  

...所以我希望上面的规则能够同时匹配问号和其他任何字符。

只有在URL中有问号时,才会有一个查询字符串,因此我建议将这两个规则分开。

如果查询字符串的开头可能有任何错误的字符,并且您要捕获URL的结尾部分(例如您在原始指令中所做的操作,例如index.html),则可以修改以上内容为:

RewriteCond %{QUERY_STRING} /(.*)$
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/%1 [NC,R,L]

请注意 substitution 字符串中的%1(而不是$1)反向引用。这是对最后匹配的 CondPattern (即/(.*)$)中捕获的组的反向引用。

您可以使用现有的指令(但要记住包含R标志)来获取更多不包含?(即查询字符串)的“普通” URL。

NB:在此示例中,用双引号引起来的参数完全是可选的。仅当 pattern substitution 自变量中有未转义的空格时,才需要

总结

# Redirect URLs of the form:
# "/Documentation/Product?<anything#1>/<anything#2>"
RewriteCond %{QUERY_STRING} /(.*)$
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/%1 [NC,R,L]

# Redirect URL-paths of the form (no query string):
# "/Documentation/Product<something>/<anything>"
RewriteRule ^Documentation/Product[^/]+/(.*) https://s3.amazonaws.com/company-documentation/Help/Product/$1 [NC,R,L]