【问题标题】:How does a RewriteRule work when the first argument is just a dot?当第一个参数只是一个点时,RewriteRule 是如何工作的?
【发布时间】:2017-10-05 12:16:06
【问题描述】:

我安装了一些 PHP 软件,在我的 .htaccess 中添加了以下内容:

RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

这是在做什么?

我的解释,这显然是错误的:它将http://foo.bar.com 捕获为http:foo.bar.com,然后用http:/foo.bar.com 替换任何字符.。绝对不是,对吧?

【问题讨论】:

  • %{REQUEST_URI} 不匹配域,它是 %{HTTP_HOST} 匹配 foo.bar.com ,让我知道你需要什么?
  • 啊,好吧。然后我错了。但无论如何,我试图了解它的作用。为什么会有双斜杠?
  • 这段代码真的给了我新的技巧来提高用户体验水平,所以当用户错误地添加一些斜线时,他应该正确,非常感谢

标签: regex apache .htaccess mod-rewrite


【解决方案1】:

它将http://foo.bar.com 捕获为http:foo.bar.com,然后将任何字符. 替换为http:/foo.bar.com。绝对不是,对吧?

对,绝对不是。 :)

该代码将同时出现在 URL 路径中的多个斜杠减少为单个斜杠。所以像example.com/foo//bar////baz 这样的URL 变成了example.com/foo/bar/baz

REQUEST_URI 服务器变量仅包含 URL 路径(以斜杠开头)。例如。 /foo//bar////baz(在上面的例子中)。 %1%2 是对最后匹配的 CondPattern 中捕获组的反向引用(即双斜杠两侧的字符串)。

RewriteRulepattern 中的单个点 (.) 匹配单个字符。因此,当 URL-path 为空时,此规则匹配除文档根目录之外的所有 URL。

为什么要检查多个斜杠?如果这些是对物理文件的请求,那么 Apache 将隐式减少多个斜杠以提供资源。所以/foo//bar////baz.html 将返回与/foo/bar/baz.html 相同的结果。所以,这就是“好”。但是,这些在技术上是不同的 URL,因此这可能会被搜索引擎视为重复内容。如果您出于其他目的解析 URL,它也可能会破坏您的应用程序。这可能是也可能不是问题。这将要求用户错误地链接到您等。(除非您的网络应用程序出现问题导致生成这些 URL。)


我要补充一点,这种方法并不是特别有效,因为如果您有许多额外的斜杠,它需要多个外部重定向(尽管您可能会争辩说这只是为了缓存边缘情况)。例如,给定/foo//bar////baz 的请求,将发生以下重定向:

  1. /foo//bar////baz(初始请求/重定向)
  2. /foo//bar///baz(重定向)
  3. /foo//bar//baz(重定向)
  4. /foo//bar/baz(重定向)
  5. /foo/bar/baz

【讨论】:

  • 哦,我明白了。第一个 RewriteRule arg 不是要替换的正则表达式,而是过滤 URL 集以转换为第二个 arg 的正则表达式。谢谢!
  • 是的,RewriteRule pattern 限制了该指令适用的 URL。理想情况下,这应该尽可能地限制 - 这是在文件中它之前的 RewriteCond 指令之前处理的第一件事。我在回答中添加了一些关于“为什么”您可能会检查 URL 中的多个斜杠的内容。
  • 您可以使用RewriteRule ^(.*)//+(.*)$ $1/$2 [R=301,L]一次性(但在一处)减少所有斜线。
  • @Croises 是的,嗯,有点......你仍然需要使用 RewriteCond 指令并检查 REQUEST_URI var,因为 RewriteRule 匹配的 URL 路径反对已经有斜线减少。您还需要使捕获的组不贪婪,否则它们也会匹配斜线并且不会有任何改进。例如。 RewriteCond %{REQUEST_URI} ^(.*?)//+(.*?)$ - 但这仍然只匹配 single 组斜杠。对于/foo////bar////baz,仍然会有 2 个重定向。但是,您可以通过使用内部重写来避免这种情况,并且只在最后重定向。
  • 很好解释+1。我已经发布了一个解决方案,可以在下面的单个重定向规则中删除所有多个斜杠。
【解决方案2】:

MrWhite has explained very nicely 解释你有问题的规则。但是,当将带有多个斜杠的 URL 发送到您的 Web 服务器时仍然存在问题,例如/foo//bar////baz。您的规则会导致 5 次重定向,然后再将其解析为 /foo/bar/baz

在他的回答下方的 cmets 部分中有一些讨论,关于在单个重定向中完成此操作的规则应该是什么。

以下规则将在单个重定向中将所有多个斜杠 URL 删除为单个斜杠 URL:

RewriteEngine On

RewriteCond %{REQUEST_URI} //
RewriteRule ^.*$ /$0 [R=301,L,NE]

它使用来自RewriteRule 指令的匹配模式的反向引用,该指令已经通过mod_rewrite 引擎获得多个无斜杠匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-15
    • 2023-04-08
    • 2014-04-11
    • 2021-01-16
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多