我编写了以下.htaccess
规则将所有 URL 从 重定向www.a.com
到www.b.com
:
RewriteEngine on
RewriteCond %{http_host} ^www.a.com [NC,OR]
RewriteCond %{http_host} ^a.com [NC]
RewriteRule ^(.*)$ https://www.b.com/myfolder/ [R=301,NC,L]
现在的子目录下有一个文件a.com
,如下所示:
www.a.com/.well-known/acme-challenge/#######
用于 AutoSSL 续订。通过上述重定向,AutoSSL 将无法再找到该文件,因此续订失败。
那么,是否可以禁用下的重定向/.well-known/acme-challenge/
?
答案1
由于您将所有内容重定向到固定的 URL 路径,因此您也可以直接在指令中构建异常RewriteRule
(无需像当前那样捕获 URL 路径)。
例如:
RewriteCond %{HTTP_HOST} ^(www\.)?a\.com [NC]
RewriteRule !^\.well-known/acme-challenge/ https://www.b.com/myfolder/ [R=301,L]
!
上的前缀RewriteRule
图案对表达式取反,因此当正则表达式满足以下条件时,即为成功:不是匹配。在这种情况下,请求的 URL 路径不是 开头.well-known/acme-challenge/
。(但是,请参阅下面的“边缘情况”。)
我也把你的两个结合起来状况(指令)合二为一。规则本身RewriteCond
不需要标志(假设您使用的是 Linux,而不是 Windows)。NC
请记住在正则表达式中使用反斜杠转义文字点。
边缘情况(可选附加项)
请注意,如果文件后面还有前端控制器模式.htaccess
(例如 WordPress、Joomla、大多数其他框架/CMS 等),那么您还应该添加一个状况上面的规则可以防止在请求表单的 URL 时重定向到前端控制器的重写/.well-known/acme-challenge/<non-existent-file>
。例如:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
:
如果没有这个条件,那么请求http://a.com/.well-known/acme-challenge/<non-existent-file>
就会被重定向到https://www.b.com/index.php
(假设index.php
是前端控制器)。
概括
完整的规则将变成:
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(www\.)?a\.com [NC]
RewriteRule !^\.well-known/acme-challenge/ https://www.b.com/myfolder/ [R=301,L]
# Front-controller pattern follows...
更新:
如果重定向只有一行简单的内容:
redirect 301 / https://www.b.com/myfolder/
,那么如何编写异常/.well-known/acme-challenge/
?
自简单的 Redirect
(mod_alias) 指令本身不提供“例外”功能,您需要将指令括在表达式中<If>
(需要 Apache 2.4)。例如:
<If "%{REQUEST_URI} !~ m#^/\.well-known/acme-challenge/#">
Redirect 301 / https://www.b.com/myfolder/
</If>
参考:https://httpd.apache.org/docs/2.4/expr.html
(如果您使用Redirect
这样的指令,那么就不存在上面提到的“前端控制器”模式和“边缘情况”。)
在旁边:虽然它们看起来很相似,但这个指令与之前使用的指令Redirect
有很大不同,并且会产生不同的结果。上面的指令RewriteRule
RewriteRule
丢弃请求的 URL 路径,将所有内容重定向到https://www.b.com/myfolder/
。但是,Redirect
此处使用的指令果酱请求的 URL 路径,在 URL 路径前加上前缀/myfolder
(例如/foo/bar
重定向到https://www.b.com/myfolder/foo/bar
)