将https://www.website.com重定向到https://website.com无法正常运行

时间:2020-03-09 07:20:22

标签: apache redirect mod-rewrite url-rewriting

我在将https://www.website.com重定向到https://website.com上发表了以下文章:

Issue with Let's Encrypt certificate : https://www.website.com not working with redirection to https://website.com

我无法实现这种重定向,我也不明白是什么原因。

如果我输入https://www.website.com,它将保留在https://www.website.com上,并且不执行重定向到https://website.com的操作。

在使用Apache2的Zope服务器上,我的配置有些特殊。

目前,下面是我的重写规则(http://www.website.comhttp//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>

这有什么问题吗?

1 个答案:

答案 0 :(得分:1)

我相信有few things of note

  1. 一个或多个RewriteCond可以位于RewriteRule指令之前。然后,仅当URI的当前状态都与它的模式匹配并且满足这些条件时,才使用以下规则。

  2. RewriteRule指令......可以多次出现,每个实例定义一个重写规则。定义这些规则的顺序很重要-这是它们在运行时应用的顺序。

  3. 在VirtualHost上下文中,模式将首先与主机名和端口之后以及查询字符串之前的URL部分匹配(例如“ /app1/index.html”)。这是(%解码的)URL路径。

  4. 如果要与主机名,端口或查询字符串匹配,请分别使用RewriteCond和%{HTTP_HOST},%{SERVER_PORT}或%{QUERY_STRING}变量。

您还使用L|last标志,这使引擎在运行RewriteRule之后停止处理其他规则。

上面的sorta可以使您了解引擎如何运行您的重写:

  1. RewriteRules被顺序处理(除非您指定L标志,否则将对所有规则执行此操作)
  2. 每个RewriteRule可以有许多RewriteCond,所有这些RewriteRule必须被考虑,然后再考虑RewriteCond。这也意味着必须分别为每个RewriteRule重复VirtualHost(但是有一个interesting technique会将RewriteRules分组为if-then-else块)
  3. 在您的情况下(HTTP_HOST上下文),默认情况下仅匹配URL路径,除非您手动匹配<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> 变量。

考虑到这一点,我发现您的重写规则存在一些问题(为了方便阅读,我交换了http和https vhosts,但这并不重要):

https://www.website.com -> https://website.com

据我所知-没有重写/cgi-bin的规则,https重写要检查的唯一位是<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>

我的建议如下:(这可能不是复制粘贴解决方案,但希望您能理解要点)

{{1}}
相关问题