apache从非www重定向到www
Posted
技术标签:
【中文标题】apache从非www重定向到www【英文标题】:apache redirect from non www to www 【发布时间】:2010-11-09 04:15:57 【问题描述】:我的网站似乎没有从非 www 重定向到 www。
我的Apache配置如下:
RewriteEngine On
### re-direct to www
RewriteCond %http_host !^www.example.com [nc]
RewriteRule ^(.*)$ http://www.example.com/$1 [r=301,nc]
我错过了什么?
【问题讨论】:
对于基于.htaccess
的解决方案,我建议对直径问题提出一个答案:***.com/a/5262044/367456
这很好,但它确实在 url 上添加了一个斜线,所以在美元之前去掉斜线。
Generic htaccess redirect www to non-www的可能重复
【参考方案1】:
使用重写引擎是解决此问题的一种非常重量级的方法。这是一个更简单的解决方案:
<VirtualHost *:80>
ServerName example.com
Redirect permanent / http://www.example.com/
</VirtualHost>
<VirtualHost *:80>
ServerName www.example.com
# real server configuration
</VirtualHost>
然后您将拥有另一个带有ServerName www.example.com
的<VirtualHost>
部分,用于您的真实服务器配置。当使用Redirect
directive 时,Apache 会自动保留/
之后的任何内容,这是一个常见的误解,即为什么这种方法不起作用(实际上它起作用)。
【讨论】:
对于一个也有 ssl 虚拟主机的网站,你如何做到这一点? 我在使用此建议时收到错误消息“example.com 上的网页导致重定向过多”。其他人有这个问题吗? @BlackDivine:反之亦然。只需将www.example
和 example
交换到示例中的任何位置即可。
@JonathanBerger 如果您的重定向太多,那么您可能没有正确配置文件。确保有 2 个虚拟主机:一个是上面的非 www,另一个是具有真实配置的 ServerName www.example.com。还要确保在 www.example.com 配置中也没有重定向(mod_alias 和 mod_rewrite)。
对于一个虚拟主机服务器,比如 example.com,我有 Redirect 301 / http://example2.com/extra/
,但是当它重定向时,它错过了尾部斜杠,这意味着 example.com/blah
转到 example2.com/extrablah
。有任何想法吗? (Apache 2.2.22)【参考方案2】:
http://example.com/subdir/?lold=13666
=> http://www.example.com/subdir/?lold=13666
RewriteEngine On
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^(.*)$ http://www.%HTTP_HOST%REQUEST_URI [R=301,L]
【讨论】:
非常简短的回答...但重点...不确定这是赞成票还是反对票 哦,太好了,这可以包含在顶层的服务器配置中(如果是的话)将适用于每个虚拟主机! 你好@burzumko,你是如何做到这一点的,这对于所有没有www的人都是如此,但是让example.com/subdi1/ws/*
在没有www的情况下通过?
我也将此解决方案用于 HTTPS 虚拟主机。只需在第三行的 http 中添加 s
。【参考方案3】:
<VirtualHost *:80>
ServerAlias example.com
RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>
【讨论】:
这对我不起作用;它导致到同一站点的无限重定向循环 @dmiller309:你是否在ServerAlias
中加入了www.
?
你说得对,我不小心放了www。在 ServerAlias 中使用 *.通配符。因为我弄乱了 VirtualHost 条目的顺序,所以 *.通配符有机会在我认为不会匹配时匹配。
这是最好的答案,因为它很干净,保持路径(与答案 #1 不同)并且不使用 Rewrite。【参考方案4】:
要从您的 URL
网站中删除 www
,请在您的 .htaccess
文件中使用此代码:
RewriteEngine On
RewriteCond %HTTP_HOST ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1$1 [R=301,L]
要在您的网站URL
中强制使用www
,请在.htaccess
上使用此代码
RewriteEngine On
RewriteBase /
RewriteCond %HTTP_HOST ^YourSite.com$
RewriteRule ^(.*)$ http://www.yourSite.com/$1 [R=301]
RewriteCond %REQUEST_fileNAME !-d
RewriteCond %REQUEST_fileNAME !-f
RewriteRule ^(([^/]+/)*[^./]+)$ /$1.html [R=301,L]
其中YourSite.com
必须替换为您的URL
。
【讨论】:
最佳答案在这里,因为它适用于具有多个域名的网站 .html 的第二部分是什么?? 移除 $1 前的斜杠,使重定向后没有双斜杠 (//) => RewriteRule ^(.*)$ yourSite.com$1 [R=301]【参考方案5】: <VirtualHost *:80>
DocumentRoot "what/ever/root/to/source"
ServerName www.example.com
<Directory "what/ever/root/to/source">
Options FollowSymLinks MultiViews Includes ExecCGI
AllowOverride All
Order allow,deny
allow from all
<What Ever Rules You Need.>
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
Redirect permanent / http://www.example.com/
</VirtualHost>
上面的代码就是这样。第一个虚拟主机块检查请求是否为 www.example.com 并在该目录中运行您的网站。
如果失败,则进入第二个虚拟主机部分。这里除了 www.example.com 之外的任何东西都被重定向到 www.example.com。
这里的顺序很重要。如果先添加第二个 virtualhost 指令,会导致重定向循环。
此解决方案会将任何请求重定向到您的域,即 www.yourdomain.com。
干杯!
【讨论】:
【参考方案6】:这与许多其他建议相似,但有一些改进:
无需对域进行硬编码(适用于接受多个域或环境之间的虚拟主机) 保留方案 (http/https) 并忽略以前的%REQUEST_URI
规则的影响。
不受之前RewriteRule
s 影响的路径部分如%REQUEST_URI
是。
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^(.*)$ %REQUEST_SCHEME://www.%HTTP_HOST/$1 [R=301,L]
【讨论】:
几乎完美。它必须是 %HTTP_HOST$1,而不是 %HTTP_HOST/$1(否则斜杠会加倍) @Michael Wyraz:这里的斜线不加倍吗?!【参考方案7】:非 www => www 和相反 www => 非 www 的重定向代码。 .htaccess 文件中没有硬编码域和方案。所以源域和http/https版本会被保留。
APACHE 2.4 及更新版本
非万维网 => 万维网:
RewriteEngine On
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^ %REQUEST_SCHEME://www.%HTTP_HOST%REQUEST_URI [R=301,L]
WWW => 非WWW:
RewriteEngine On
RewriteCond %HTTP_HOST ^www\.(.*)$ [NC]
RewriteRule ^ %REQUEST_SCHEME://%1%REQUEST_URI [R=301,L]
注意:不能在 %REQUEST_SCHEME 不可用的 Apache 2.2 上工作。为了与 Apache 2.2 兼容,请使用以下代码或将 %REQUEST_SCHEME 替换为固定的 http/https。
APACHE 2.2 及更新版本
非万维网 => 万维网:
RewriteEngine On
RewriteCond %HTTPS off
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^ http://www.%HTTP_HOST%REQUEST_URI [R=301,L]
RewriteCond %HTTPS on
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^ https://www.%HTTP_HOST%REQUEST_URI [R=301,L]
...或更短的版本...
RewriteEngine On
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteCond %HTTPSs ^on(s)|offs
RewriteRule ^ http%1://www.%HTTP_HOST%REQUEST_URI [R=301,L]
WWW => 非WWW:
RewriteEngine On
RewriteCond %HTTPS off
RewriteCond %HTTP_HOST ^www\.(.*)$ [NC]
RewriteRule ^ http://%1%REQUEST_URI [R=301,L]
RewriteCond %HTTPS on
RewriteCond %HTTP_HOST ^www\.(.*)$ [NC]
RewriteRule ^ https://%1%REQUEST_URI [R=301,L]
... 不能使用更短的版本,因为 %N 仅在最后一个 RewriteCond 中可用...
【讨论】:
Apache 2.4 配置解决了这个问题,感谢您的干净回答..!!【参考方案8】:RewriteCond %HTTP_HOST ^!example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
这从 HTTP_HOST
变量开始,它只包含传入 URL (example.com
) 的域名部分。假设域名不包含www.
并且与您的域名完全匹配,那么 RewriteRule 就会发挥作用。模式^(.*)$
将匹配REQUEST_URI
中的所有内容,这是HTTP 请求(foo/blah/index.html
) 中请求的资源。它将其存储在反向引用中,然后用于用新域名(以 www
开头的域名)重写 URL。
[NC]
表示不区分大小写的模式匹配,[R=301]
表示使用代码 301 的外部重定向(资源永久移动),[L]
停止所有进一步的重写,并立即重定向。
【讨论】:
【参考方案9】:如果您使用的是 Apache 2.4,则无需启用 rewrite apache 模块,您可以使用以下内容:
# non-www to www
<If "%HTTP_HOST = 'domain.com'">
Redirect 301 "/" "http://www.domain.com/"
</If>
【讨论】:
被低估的答案。使用它,可以避免额外的虚拟主机,这对于自动化 Let'sEncrypt 脚本很有好处。 另外,如果您使用的是 ANSIBLE,从 ANSIBLE 2.0 开始,您现在可以在一个任务中轻松地将块插入文件中,更多详细信息请点击此处docs.ansible.com/ansible/2.5/modules/blockinfile_module.html【参考方案10】:我跑了这个...
RewriteEngine on
RewriteCond %HTTP_HOST !^www.*$ [NC]
RewriteRule ^/.+www\/(.*)$ http://www.%HTTP_HOST/$1 [R=301,L]
我需要它对我们新服务器上的 25+ 个域是通用的,所以这个指令在我的 virtual.conf 文件中的
尽管http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html 说它只是在主机和端口之后的东西,但我不得不对重写规则进行一些修改,因为完整的 docroot 正在模式匹配中进行。
【讨论】:
【参考方案11】:将 domain.tld 重定向到 www。
可以在 Apache 指令或 .htaccess 文件中添加以下行:
RewriteEngine on
RewriteCond %HTTP_HOST .
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^ http%ENV:protossl://www.%HTTP_HOST%REQUEST_URI [L,R=301]
其他 sudomains 仍在工作。
无需调整线条。只需将它们复制/粘贴到正确的位置即可。
如果您修改虚拟主机,请不要忘记应用 apache 更改。
(基于默认的 Drupal7 .htaccess 但在许多情况下应该可以工作)
【讨论】:
【参考方案12】:这很简单!
RewriteEngine On
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^(.*)$ http://www.%HTTP_HOST%REQUEST_URI [R=301,L]
【讨论】:
【参考方案13】:<VirtualHost *:80>
ServerAlias example.com
RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>
这不仅会重定向域名,还会重定向内部 pages.like... example.com/abcd.html ==> www.example.com/abcd.html example.com/ab/cd.html?ef=gh ==>强> www.example.com/ab/cd.html?ef=gh
【讨论】:
谢谢。很有帮助。【参考方案14】:试试这个:
RewriteEngine on
RewriteCond %HTTP_HOST ^example.com$ [NC]
RewriteRule ^(.*) http://www.example.com$1 [R=301]
【讨论】:
【参考方案15】:不要总是使用Redirect permanent
(或者为什么它可能会在未来引起问题)
如果以后有机会添加子域,请不要使用redirect permanent
。
因为如果客户使用了未注册为 VirtualHost
的子域,即使稍后注册,他也可能永远无法访问此子域。
redirect permanent
向客户端(浏览器)发送一个HTTP 301 Moved Permanently
,其中很多会永久缓存此响应(直到[手动]清除缓存)。因此,使用该子域将始终自动重定向到 www.*** 而无需再次请求服务器。
见How long do browsers cache HTTP 301s?
所以只需使用Redirect
<VirtualHost *:80>
ServerName example.com
Redirect / http://www.example.com/
</VirtualHost>
Apache.org - When not to use mod_rewrite
Apache.org - Canonical Hostnames
【讨论】:
【参考方案16】:RewriteEngine On
RewriteCond %HTTP_HOST ^yourdomain.com [NC]
RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [L,R=301]
检查这个完美的工作
【讨论】:
【参考方案17】:-如果您托管多个域名(可选)
-如果所有这些域名都使用 https(应该如此)
-如果您希望所有这些域名都使用 www dot domainName
这将避免双重重定向(http://non www 到 http://www 然后到 https://www)
<VirtualHost *:80>
RewriteEngine On
RewriteCond %HTTP_HOST ^(?:www\.)?(.+)$ [NC]
RewriteRule ^(.*)$ https://www.%1$1 [R=301,L]
</VirtualHost>
和
<VirtualHost *:443>
RewriteEngine On
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^(.*)$ https://www.%HTTP_HOST$1 [R=301,L]
</VirtualHost>
你应该把重定向代码301改成最方便的一个
【讨论】:
【参考方案18】:到 301 将所有直接向域发出的请求重定向到您可以使用的 www:
RewriteEngine On
RewriteCond %HTTP_HOST !^([^.]+\.[^.]+)2,$ [NC]
RewriteRule ^(.*)$ http://www.%HTTP_HOST%REQUEST_URI [R=301,L]
这样做的好处是,如果您有任何有效的子域,这将起作用,例如
example.com 已重定向到 www.example.com
foo.example.com 没有重定向
bar.example.com 没有重定向
【讨论】:
【参考方案19】:我也遇到了同样的问题。 但解决了这个
RewriteEngine On
RewriteCond %HTTP_HOST !^www\.
RewriteRule ^(.*)$ http://www.%HTTP_HOST/$1 [R=301,L]
此规则将非 www 重定向到 www。
这个规则将www重定向到非www
RewriteEngine On
RewriteCond %HTTP_HOST !^my-domain\.com$ [NC]
RewriteRule ^(.*)$ http://my-domain.com/$1 [R=301,L]
参考http://dense13.com/blog/2008/02/27/redirecting-non-www-to-www-with-htaccess/
【讨论】:
【参考方案20】:这对我有用:
RewriteCond %HTTP_HOST ^(?!www.domain.com).*$ [NC]
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301,L]
在将所有域重定向到 www
子域时,我使用前瞻模式 (?!www.domain.com)
排除 www
子域,以避免 Apache 中的无限重定向循环。
【讨论】:
【参考方案21】:我使用的代码是:
RewriteEngine On
RewriteBase /
RewriteCond %HTTP_HOST ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
【讨论】:
【参考方案22】:如果您只想加载 https 版本的 www,请在 apache 虚拟主机文件中使用以下配置。所有这些都可以包含在一个文件中。
将所有http重定向到www的https:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
将 https 非 www 重定向到 https www:
<VirtualHost *:443>
ServerName example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
真实服务器配置
<VirtualHost *:443>
ServerAdmin hostmaster@example.com
DocumentRoot "/path/to/your/sites/.htaccess-file-folder"
SetEnv APPLICATION_ENV "production"
<Directory "/path/to/your/sites/.htaccess-file-folder">
Options Indexes FollowSymLinks
DirectoryIndex index.php index.html
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ServerName www.example.com
SSLEngine ON
SSLCertificateFile "/path/to/your/example.cert.pem"
SSLCertificateKeyFile "/path/to/your/example.key.pem"
ErrorLog /path/to/your/example.com-error.log
CustomLog /path/to/your/example.com-access.log combined
#Your other configurations if you have
</VirtualHost>
【讨论】:
【参考方案23】:这是我自己网站的配置,效果很好。
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin admin@domain.com
ServerName www.domain.com
ServerAlias domain.com
DocumentRoot /var/www/html/domain
<Directory /var/www/html/domain/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Redirect non-www to www
RewriteEngine On
RewriteCond %HTTP_HOST !^www\. [NC]
RewriteRule ^(.*)$ https://www.%HTTP_HOST%REQUEST_URI [R=301,L]
ErrorLog $APACHE_LOG_DIR/error.log
CustomLog $APACHE_LOG_DIR/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem
</VirtualHost>
</IfModule>
【讨论】:
【参考方案24】:如果使用上述两个<VirtualHost *:80>
块的解决方案不同ServerName
s...
<VirtualHost *:80>
ServerName example.com
Redirect permanent / http://www.example.com/
</VirtualHost>
<VirtualHost *:80>
ServerName www.example.com
</VirtualHost>
...那么您也必须设置NameVirtualHost On
。
如果您不这样做,Apache 不允许自己使用不同的ServerName
s 来区分块,因此您会收到以下错误消息:
[warn] _default_ VirtualHost overlap on port 80, the first has precedence
...要么没有重定向发生,要么你有一个无限的重定向循环,这取决于你先放哪个块。
【讨论】:
【参考方案25】:我在 WP Multisite 上有一个类似的任务,其中重定向规则必须是通用的(对于我要添加到网络的任何给定域)。我首先解决了向域(停放域)添加通配符的问题。注意 . .com 之后。
CNAME * domain.com.
然后我将以下行添加到多站点根目录下的 .htaccess 文件中。我想它适用于任何网站。
RewriteEngine On
RewriteBase /
RewriteCond %HTTP_HOST ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
希望这会有所帮助。
ps。如果您想从非 www 重定向到 www,请将最后一行更改为
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
【讨论】:
【参考方案26】:我发现在使用多个虚拟主机时使用 ServerAlias 更容易(也更有用)。
<VirtualHost x.x.x.x:80>
ServerName www.example.com
ServerAlias example.com
....
</VirtualHost>
这也适用于 https 虚拟主机。
【讨论】:
另一个开车通过的downvote。想解释一下,哦,伟大的 httpd 之神,谁懒得解释反对票? 这使得您有多个域托管同一个站点。根据您的情况和底层网络服务器的运行情况,您可能会遇到 cookie 无法保留、人们感到困惑以及搜索引擎问题(这将被视为 2 个不同的站点)的问题。以上是关于apache从非www重定向到www的主要内容,如果未能解决你的问题,请参考以下文章
如何在 aws s3 存储桶和云端执行从非 www 到 www 的 301 重定向