Apache HTTPD RewriteRule 中的 ^ 和 $ 是什么意思?

What is the meaning of ^ and $ in Apache HTTPD RewriteRule?

我已成功将以下代码添加到我的 Apache HTTPD 配置中:

# Force www.
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/ [R=301,L]
# Force https (SSL)
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

虽然按预期工作,但我有一个理论问题:

为什么第3行有^$"www.",而第6行没有"https"?

此致,多维德。

这取决于您是为不带 www 还是带 www 的域制作证书。

在提供的示例中,重定向(第 6 行)是在 没有 www 的情况下完成的。这保证了正确的证书将被提供并且浏览器在访问您的站点时不会显示警报。

他们是一样的。 ^(.*)$(.*) 没有区别。

.* 匹配任何字符串。 ^$ 不会改变这一点,因为所有字符串都有开始和结束。

对于您的两个正则表达式模式,^(.*)$(.*) 将表现相同。但是你猜怎么着,你不需要使用它们中的任何一个。事实上,不使用 .* 和使用匹配完整 URI 的 %{REQUEST_URI} 变量(而不是像 .* 这样的相对变量)也不容易出错。所以我建议将您的规则更改为:

# Force www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

# Force https (SSL)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
  • Flag NE用于不转义。如果您的原始 URI 有一些特殊字符,如 #(,),[,]
  • ,则使用此标志很有用 上面 RewriteRule 模式中的
  • ^ 除了 returns 之外什么都不做,因为 ^ 表示字符串的开始位置并且它将始终匹配。
  • 两个规则可以合并为一个规则,但看起来会有点复杂。

这里是:

RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]

这条规则的解释如下:

  • RewriteCond %{HTTP_HOST} !^www\. [NC,OR]:如果 HOST_NAME 不是以 www.
  • 开头
  • [NC,OR]: 忽略大小写匹配和OR下一个条件
  • RewriteCond %{HTTPS} !on: HTTPS 未开启
  • RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]:此条件将始终匹配,因为 www. 在这里是可选匹配。它用于通过使用捕获组 #1 中的 (.+) 模式捕获 HTTP_HOST 的子字符串而不开始 www.(稍后将被反向引用为 %1)。请注意,(?:..) 是一个非捕获组。
  • RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]: ^ 将始终匹配。通过将 https://www. 添加到 %1,此规则将使用 R=301 代码重定向到 https://www.%1%{REQUEST_URI}%1 是来自 RewriteCond 的捕获组 #1 的反向引用,如上所述。

如果使用 Apache 的模块 mod_rewrite then you can define a RewriteRule

RewriteRule 使用正则表达式

关键字或指令 RewriteRule 后跟 Regular Expression(也称为 RegEx模式)。此 RegEx(例如 ^(.*)$)用于匹配输入 URL 以重写它们。

正则表达式使用特殊字符编码

RegEx 模式中,^ 标记要匹配的行的开始,而结束由 $ 表示。

两者都称为元字符并且具有特殊含义:

^: Matches the starting position within the string. In line-based tools, it matches the starting position of any line.

$: Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.

为什么它们经常过时?

由于到达 HTTP 服务器的 URLs 总是由一行表示,这些 行定界 元字符也可以省略而不影响 pattern/rewrite-rule.