Apache HTTPD RewriteRule 中的 ^ 和 $ 是啥意思?
Posted
技术标签:
【中文标题】Apache HTTPD RewriteRule 中的 ^ 和 $ 是啥意思?【英文标题】:What is the meaning of ^ and $ in Apache HTTPD RewriteRule?Apache HTTPD RewriteRule 中的 ^ 和 $ 是什么意思? 【发布时间】:2020-04-12 11:14:33 【问题描述】:我已成功将以下代码添加到我的 Apache HTTPD 配置中:
# Force www.
RewriteCond %HTTP_HOST !^www\.
RewriteRule ^(.*)$ https://www.%HTTP_HOST/$1 [R=301,L]
# Force https (SSL)
RewriteCond %HTTPS off
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R=301,L]
虽然它按预期工作,但我有一个理论上的问题:
为什么在第 3 行有一个 ^
和 $
强制执行“www.”,而不是在第 6 行强制执行“https”?
此致,多维德。
【问题讨论】:
【参考方案1】:对于您的两个正则表达式模式^(.*)$
和(.*)
将表现相同。但是你猜怎么着,你不需要使用它们中的任何一个。事实上,不使用.*
并使用匹配完整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]
标志NE
用于不转义。如果您的原始 URI 包含一些特殊字符,例如 #
或 (,),[,]
等,则使用此标志很有用。
上面RewriteRule
模式中的^
什么都不做,只会为每个匹配项返回true,因为^
表示字符串的开始位置,它将始终匹配。
这两个规则可以组合成一个规则,但看起来有点复杂。
这里是:
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
s 下一个条件
RewriteCond %HTTPS !on
:HTTPS
未开启
RewriteCond %HTTP_HOST ^(?:www\.)?(.+)$ [NC]
:此条件将始终匹配,因为 www.
在此处是可选匹配。它用于捕获HTTP_HOST
的子字符串,而无需在捕获组#1 中使用(.+)
模式启动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 的反向引用,如上所述。
【讨论】:
【参考方案2】:如果使用 Apache 的模块 mod_rewrite,那么您可以定义一个 RewriteRule。
RewriteRule 使用正则表达式
关键字或指令 RewriteRule
后跟 Regular Expression(也称为 RegEx 或 pattern)。此 RegEx(例如 ^(.*)$
)用于匹配输入 URL 以便重写它们。
正则表达式使用特殊字符编码
在 RegEx 模式中,^
标记要匹配的行的开头,而结尾由 $
表示。
两者都称为元字符并具有特殊含义:
^:匹配字符串中的起始位置。在基于行的工具中,它匹配任何行的起始位置。
$:匹配字符串的结束位置或字符串结束换行符之前的位置。在基于行的工具中,它匹配任何行的结束位置。
为什么它们经常过时?
由于到达 HTTP 服务器的 URL 总是由一行表示,这些 行分隔 元字符也可以省略而不影响模式/重写规则。
【讨论】:
B"H 你好 hc_dev 我现在明白为什么在这种情况下没有区别,谢谢你。真诚的,Dovid。【参考方案3】:它们是一样的。 ^(.*)$
和 (.*)
没有区别。
.*
匹配任何字符串。 ^
和 $
不要更改它,因为所有字符串都有开始和结束。
【讨论】:
B"H 感谢匿名者的回复。在任何文档中都提到过吗?此致,Dovid。 @Dovid 这些是正则表达式控制字符。^
表示“字符串的开头”。 $
表示“字符串结束”。在这种特定的情况下,它们具有相同的含义。在其他情况下,它们可能很重要。
@Dovid 否,但httpd.apache.org/docs/current/rewrite/intro.html 上有一些示例显示.*
匹配所有内容。 ^
和 $
不要改变它。
B"H 再次感谢匿名用户的额外回复。此致,Dovid。
不要做那种不加解释就...简洁地回答的人;-)【参考方案4】:
这取决于您是否为不带 www 或带 www 的域制作了证书。
在提供的示例中,重定向(第 6 行)是对域 没有 www。这样可以保证提供正确的证书,并且浏览器在访问您的网站时不会显示警报。
【讨论】:
B"H 感谢 Skatox 的回复。如果没有“www.”,则代码的前半部分(第 3 行)会同时添加“www.”和“https”。如果“www.”已经存在,那么第 6 行中“HTTP_HOST”的那部分不是吗?因为如果不是,那么地址将保留没有“www.”,而实际上是“www.”。总是添加。我必须承认,我不知道如何检查两者中的哪一个,www。或非 www.,有我的 Hostgator 提供商颁发给它的证书。甚至不知道这有什么不同。此致,多维德。 HTTP_HOST 只是域,没有别的。如果我的回答帮助您记得将其标记为已解决并投票:)以上是关于Apache HTTPD RewriteRule 中的 ^ 和 $ 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章