htaccess vs virtualhost - 插入符匹配^

问题描述 投票:0回答:1

我一直在为客户想出一些重定向,他们需要在 domain.com 上进行重定向以具有前导 www,而 sub.another.com 已别名为 domain.com 以不具有前导 www。我找到了一个 solution,它有点管用。

我的前辈告诉我,仅插入符匹配(例如

RewriteRule ^
部分)在.htaccess中不起作用,显然只在虚拟主机中起作用。我知道它们之间存在一些细微差别,但我找不到任何来源(他也无法提供)说
^
匹配在.htaccess中不起作用。

显然,正确的规则是

RewriteRule ^(.*) https://sub.another.com/$1 [R=301,L]
。谁能解释为什么匹配在 .htaccess 中不起作用?如果相信互联网,
^
^(.*)
应该匹配整行。后者明确指示匹配行首之后的任何内容,而前者匹配行本身的开头(因此也应匹配空字符串,请参阅this answer)。

regex .htaccess
1个回答
0
投票

我的前辈告诉我,仅插入符号匹配(例如

RewriteRule ^
部分)在
.htaccess
中不起作用,显然只在虚拟主机中

那是废话。

^
(正则表达式语法)只是断言字符串的开头。而已。因此,如果参数采用正则表达式(无论上下文如何),
^
总是会“起作用”,具体取决于您要匹配的内容。 (我想知道你是不是真的指 URL 路径上的斜杠前缀?)

显然只在虚拟主机中

你可以说事实恰恰相反。

^$
将在
.htaccess
中匹配,但不会在虚拟主机上下文中匹配。 (这与
.htaccess
上下文中的根目录/主页匹配。)

这仅仅是由于在这些不同的contexts中匹配的内容。 (Apache 配置中有 4 个上下文:

.htaccess
directoryvirtualhostserver。)

virtualhost 上下文中,

RewriteRule
pattern 匹配完整的根相对 URL 路径,以斜杠开头。因此,您需要匹配
^$
而不是
^/$
(以匹配根目录)。

而在

.htaccess
(和 directory)上下文中,匹配的 URL 路径是相对于包含
.htaccess
文件的目录(目录前缀已被删除),因此 not 以一个斜线。

例如,给定网址

https://example.com/foo/bar/baz
...

  • 在虚拟主机上下文中,

    RewriteRule
    pattern 匹配 URL 路径
    /foo/bar/baz
    (以斜杠开头的完整 URL 路径。)

  • 在根目录的

    .htaccess
    中,然后
    RewriteRule
    pattern匹配
    foo/bar/baz
    (无斜杠前缀)。但是如果
    .htaccess
    文件位于
    /foo
    子目录(不是根目录)中,那么匹配的 URL 路径是:仅
    bar/baz
    (省略
    /foo
    )。

显然,正确的规则是

RewriteRule ^(.*) https://sub.another.com/$1 [R=301,L]
。任何人都可以解释为什么比赛在
.htaccess
中不起作用吗?

确实

.htaccess
中工作。事实上,这只会在
.htaccess
中正常工作,因为如果您在 virtualhost 上下文中使用此规则,那么您将在重定向请求中的 URL 路径的开头以双斜杠结束。 (当然,其他规则可以影响此行为,
.htaccess
文件的位置 - 如果在子目录中 - 也会改变此行为。)

如果相信互联网,

^
^(.*)
应该匹配整行

^
本身并不 match 任何东西,它只是断言字符串的开头,所以总是“成功”。而
^(.*)
断言字符串的开头,然后匹配 URL 路径的其余部分并在反向引用中捕获它。事实上,
^
中的
^(.*)
前缀是完全可选的(匹配 URL 路径时),因为正则表达式是 greedy
^(.*)
(.*)
是“相同的”。

由于您在

substitution
字符串中使用了 $1 反向引用,因此您需要实际捕获某些内容,因此您需要
(.*)
(因为
^
不匹配/捕获任何内容,它只是一个 assertion)。但这都是一样的,无论您在哪里使用此指令:
.htaccess
virtualhost.

在此特定规则中,您可以仅使用

^
并在
substitution
字符串中使用 REQUEST_URI 服务器变量。例如:

RewriteRule ^ https://sub.another.com%{REQUEST_URI} [R=301,L]

请注意,

REQUEST_URI
变量包含整个 URL 路径,包括斜杠前缀,因此在 substitution 字符串中省略了斜杠。该规则可以说比使用反向引用(您上面的规则)“更好”,因为它适用于anywhere(任何目录),无论上下文如何,并且使用更有效的正则表达式。

© www.soinside.com 2019 - 2024. All rights reserved.