[我就https://www.website.com
到https://website.com
的重定向发表以下帖子:
我无法实现这种重定向,我也不明白是什么原因。
如果我键入https://www.website.com
,它将保留在https://www.website.com
上,并且不执行重定向到https://website.com
的操作。
我的配置在使用Apache2的Zope服务器上有点特殊。
目前,这是我的重写规则(http://www.website.com
和http//website.com
都被正确地重定向到https://website.com
):
<VirtualHost *:443>
# REWRITE to get https://www.website.com to https://website.com except for cgi-bin scripts
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/cgi-bin/search [NC]
RewriteCond %{REQUEST_URI} !^/cgi-bin/awstats [NC]
RewriteRule ^/(.*) https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]
</VirtualHost>
<VirtualHost *:80>
<IfModule mod_rewrite.c>
# www to non www for HTTP and HTTPS
RewriteCond %{REQUEST_URI} ^/www\. [NC,OR]
RewriteCond %{REQUEST_URI} !^/podcast [NC]
# Rewrite below works : redirect 80 => https
RewriteRule ^/(.*) https://website.com/$1 [R=301,L]
RewriteRule ^/(.*) http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L]
</IfModule>
</VirtualHost>
[如果有人可以看到怎么了?问候
- 一个或多个RewriteCond可以在RewriteRule指令之前。然后,仅当URI的当前状态都与它的模式匹配并且满足这些条件时,才使用以下规则。
- RewriteRule指令......可以多次出现,每个实例定义一个重写规则。定义这些规则的顺序很重要-这是它们在运行时应用的顺序。
- 在VirtualHost上下文中,模式将首先与主机名和端口之后,查询字符串之前的URL部分匹配(例如“ /app1/index.html”)。这是(%解码的)URL路径。
- 如果要与主机名,端口或查询字符串匹配,请分别将RewriteCond与%{HTTP_HOST},%{SERVER_PORT}或%{QUERY_STRING}变量一起使用。
您还使用L|last标志,这使引擎在运行RewriteRule
之后停止处理其他规则。
上面的排序使您了解了引擎如何运行您的重写:
RewriteRules
被顺序处理(除非您指定对所有规则都执行的L
标志)]RewriteRule
可以有多个RewriteCond
,所有这些都必须匹配,然后才考虑RewriteRule
。这也意味着必须分别为每个RewriteCond
重复RewriteRule
(但是有一个interesting technique将RewriteRules分组为if-then-else块)VirtualHost
上下文),默认情况下,仅URL路径是匹配的,除非您手动匹配HTTP_HOST
变量。<VirtualHost *:80> <!-- your http:// requests will end up with this block, because 80 is the port for http -->
<IfModule mod_rewrite.c>
# www to non www for HTTP and HTTPS <!-- I believe HTTPS traffic is NOT handled by this vhost at all, it arrives straight to *:443 queue -->
RewriteCond %{REQUEST_URI} ^/www\. [NC,OR] <!-- you evaluate path component of your request uri to begin with "www." (i.e. /www.index.html) - this will obviously never match, you however have OR flag, which proceeds to the second condition -->
RewriteCond %{REQUEST_URI} !^/podcast [NC] <!-- you check if the path does not start with "/podcast" - this is easy to test - try http://www.website.com/podcast and see if you get redirected to HTTPS - I suspect you will not -->
# Rewrite below works : redirect 80 => https <!-- I suspect it works by accident, please test it out with http://www.website.com/podcast to confirm my theory -->
RewriteRule ^/(.*) https://website.com/$1 [R=301,L] <!-- we end up here, and regardless of the requested path we issue a 301 redirect to https version of the website. This is marked as Last rule, so the engine should stop processing here -->
RewriteRule ^/(.*) http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L] <!-- this I believe kicks in when you request a "/podcast" path - this will proxy the request to your http://localhost:9674/ -->
</IfModule>
</VirtualHost>
<VirtualHost *:443><!-- this is where your 301 redirect will com after bouncing through first set of rules above -->
# REWRITE to get https://www.website.com to https://website.com except for cgi-bin scripts
RewriteEngine On <!-- this is important, keep it on -->
RewriteCond %{REQUEST_URI} !^/cgi-bin/search [NC] <!-- you check whether url path does not contain /cgi-bin/search -->
RewriteCond %{REQUEST_URI} !^/cgi-bin/awstats [NC]<!-- AND does not contain /cgi-bin/awstats-->
RewriteRule ^/(.*) https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]<!-- if both conditions above are met - proxy the request to backend and stop further processing. -->
</VirtualHost>
据我所知-没有重写https://www.website.com -> https://website.com
的规则,https重写检查的唯一位是/cgi-bin
我的建议将遵循以下几行(它可能不是复制粘贴的解决方案,但希望您能掌握要点):
<VirtualHost *:443> RewriteEngine On # www to non www for HTTPS <!-- checking for the same thing again --> RewriteCond %{HTTP_HOST} ^www\.(.+) [NC] RewriteRule ^/(.*) https://website.com/$1 [R=301,L] <!-- some people might argue second redirect here is excessive since you already arrived at correct host, but I'd leave this for you to sort out --> <!-- your /cgi-bin checks can be merged into one regex --> RewriteCond %{REQUEST_URI} !^/cgi-bin/(search|awstats) [NC] RewriteRule ^/(.*) https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L] </VirtualHost> <VirtualHost *:80> <IfModule mod_rewrite.c> # www to non www for HTTP <!-- if you want to keep your `/podcast` on http check it first --> RewriteCond %{REQUEST_URI} !^/podcast [NC] RewriteRule ^/(.*) http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L] <!-- everything else will get redirected to https --> RewriteCond %{HTTP_HOST} ^www\.(.+) [NC] RewriteRule ^/(.*) https://website.com/$1 [R=301,L] </IfModule> </VirtualHost>