我正在尝试将www重定向到非www以获取HTTP和HTTPS请求。我的根.htaccess看起来像这样:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^(.*)$ http://example.com/$1 [R=301]
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteCond %{SERVER_PORT} ^443
RewriteRule ^(.*)$ https://example.com/$1 [R=301]
这没有按预期完全正常工作。会发生什么:
访问http://www.example.com
会导致重定向到http://example.com
。这表明我的第一个规则和条件正在运行,mod_rewite模块是hunky-dory并且.htaccess已启用OK。
访问https://www.example.com
不会导致重定向。我留在https://www.example.com
我的问题
为了使上述重写规则有效,我的服务器必须有SSL证书吗?它目前没有,我想知道这是否是事情不起作用的原因。
答案 0 :(得分:3)
也许您可以尝试以下方法:
{{1}}
答案 1 :(得分:1)
第一条规则优先于https
请求,因为它只是满足重写条件。第一条规则基本上告诉你匹配域名,你可以让你的重写开始。而是添加另一个条件,告诉它是否不是https
请求
所以试试这个:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteCond %{SERVER_PORT} !^443
RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteCond %{SERVER_PORT} ^443
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
您需要https
协议的ssl证书才能工作
此外,我已添加[L]
标志,告知不处理其他规则
答案 2 :(得分:1)
受@MikeRockétt的回答启发,这是一个“简化”版本,仅使用一个条件(而不是三个条件)。这也会规范化FQDN(例如,通过删除主机名上的可选尾随点):
RewriteEngine On
RewriteCond %{HTTP_HOST}#%{HTTPS}s ^www\.(.+?)\.?#(?:on(s)|)
RewriteRule ^ http%2://%1%{REQUEST_URI} [R=301,L]
此301将www重定向到非www,同时保持相同的协议HTTP或HTTPS。可以在.htaccess
(目录上下文)或主服务器config / vhost中不变使用。 (尽管,如果您处于 virtualhost 上下文中,则可能应该使用更简单的mod_alias Redirect
。)
将 TestString %{HTTP_HOST}#%{HTTPS}s
(其结果为格式为“ www.example.com#ons”的字符串)与 CondPattern ^www\.(.+?)\.?#(?:on(s)|)
对于任何Host
头以“ www。”开头的请求,条件是成功的。
^www\.(.+?)\.?
首先检查Host
以“ www”开头。 (如果不是,则提前失败)并在%1
反向引用中捕获剩余的主机头(不包括可选的尾随点)。捕获域名的正则表达式,即。 (.+?)
设为非贪婪,因此它不会捕获结尾的可选点。
#
只是一个任意字符,用于分隔两个值HTTP_HOST
和HTTPS
。重要的是,#
本身不能出现在这两个值中。(?:on(s)|)
是一个非捕获组,它使用 alternation 与%{HTTPS}s
进行匹配。它要么匹配on(s)
并捕获“ s”(在%2
后向引用中),要么匹配任何内容却不捕获任何内容(因此%2
为空)。 / li>
成功提供了先前的条件,然后评估 substitution 字符串(http%2://%1%{REQUEST_URI}
)并重定向请求。来自上一个 CondPattern 的后向引用%2
包含“ s”(在 substitution 中为“ https”)或为空(即“ http”),而%1
是主机名,而不是“ www”。前缀。
REQUEST_URI
服务器变量包含完整的URL路径,包括斜杠前缀。
我的服务器必须具有SSL证书吗?
是,否则浏览器将阻止连接(抱怨无效的安全证书)-或只是超时(因为您的服务器在端口443上没有响应)并且请求甚至不会到达您的服务器。