apache从非www重定向到www

时间:2009-07-08 20:22:23

标签: apache redirect mod-rewrite no-www

我的网站似乎没有从非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] 

我错过了什么?

24 个答案:

答案 0 :(得分:481)

使用重写引擎是解决此问题的一种非常重要的方法。这是一个更简单的解决方案:

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / http://www.example.com/
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
    # real server configuration
</VirtualHost>

然后,您将有另一个<VirtualHost>部分ServerName www.example.com用于您的真实服务器配置。使用Redirect directive时,Apache会在/之后自动保留任何内容,这是一个常见的错误概念,说明为什么这种方法不起作用(事实上它确实如此)。

答案 1 :(得分:76)

http://example.com/subdir/?lold=13666 =&gt; http://www.example.com/subdir/?lold=13666

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

答案 2 :(得分:44)

<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>

答案 3 :(得分:30)

要从www网站中删除URL,请在.htaccess文件中使用此代码:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1$1 [R=301,L]

强制www在您的网站URL中使用此代码.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

答案 4 :(得分:21)

    <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。

干杯!

答案 5 :(得分:15)

这与许多其他建议类似,但有一些增强功能:

  • 无需对域进行硬编码(适用于接受多个域或环境之间的虚拟主机)
  • 保留方案(http / https)并忽略先前%{REQUEST_URI}规则的效果。
  • 不受RewriteRule之前的%{REQUEST_URI}影响的路径部分是。

    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ %{REQUEST_SCHEME}://www.%{HTTP_HOST}/$1 [R=301,L]
    

答案 6 :(得分:10)

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)。它将它存储在后引用中,然后用于使用新域名重写URL(以www开头的域名)。

[NC]表示不区分大小写的模式匹配,[R=301]表示使用代码301的外部重定向(资源永久移动),[L]停止所有进一步的重写,并立即重定向。

答案 7 :(得分:5)

我跑了这个......

 RewriteEngine on
 RewriteCond %{HTTP_HOST} !^www.*$ [NC]
 RewriteRule ^/.+www\/(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

我需要在新服务器上对25个以上的域进行通用,因此该指令位于&lt; Directory&gt;中的virtual.conf文件中。标签。 (dir是所有docroots的父母)

我不得不对重写规则进行一些修改,因为完整的docroot正在进行模式匹配,尽管http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html说它只是在主机和端口之后的东西。

答案 8 :(得分:5)

非www =&gt;的重定向代码www和对面www =&gt;非www。 .htaccess文件中没有硬编码域和方案。因此将保留原始域和http / https版本。

APACHE 2.4和NEWER

非WWW =&gt; WWW:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ %{REQUEST_SCHEME}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

WWW =&gt; NON-WWW:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ %{REQUEST_SCHEME}://%1%{REQUEST_URI} [R=301,L]

注意:不在Apache 2.2上工作,其中%{REQUEST_SCHEME}不可用。为了与Apache 2.2兼容,请使用下面的代码或将%{REQUEST_SCHEME}替换为固定的http / https。

APACHE 2.2和NEWER

非WWW =&gt; WWW:

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 %{HTTPS}s ^on(s)|offs
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

WWW =&gt; NON-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获得...

答案 9 :(得分:3)

如果您使用的是Apache 2.4,无需启用重写apache模块,您可以使用以下内容:

# non-www to www
<If "%{HTTP_HOST} = 'domain.com'">
  Redirect 301 "/" "http://www.domain.com/"
</If>

答案 10 :(得分:3)

将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仍在使用。
  • 无需调整线条。只需将它们复制/粘贴到正确的位置即可。

如果修改vhost,请不要忘记应用apache更改。

(基于默认的Drupal7 .htaccess但在很多情况下应该有效)

答案 11 :(得分:2)

试试这个:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*) http://www.example.com$1 [R=301]

答案 12 :(得分:2)

<VirtualHost *:80>
    ServerAlias example.com
    RedirectMatch permanent ^/(.*) http://www.example.com/$1
</VirtualHost>

这不仅会重定向域名,还会重定向内部域名  pages.like ...

 example.com/abcd.html ==&gt; www.example.com/abcd.html
example.com/ab/cd.html?ef=gh ==&gt ; www.example.com/ab/cd.html?ef=gh

答案 13 :(得分:1)

RewriteEngine On RewriteCond %{HTTP_HOST} ^yourdomain.com [NC] RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [L,R=301]

检查这项完美的工作

答案 14 :(得分:1)

不要总是使用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

答案 15 :(得分:1)

这很简单!

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

答案 16 :(得分:1)

-如果您托管多个域名(可选)

-如果所有这些域名都使用https(应有的话)

-如果您希望所有这些域名都使用www点domainName

这将避免双重重定向(从http://非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更改为最方便的

答案 17 :(得分:0)

我刚遇到同样的问题。 但是用这个解决了

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/

答案 18 :(得分:0)

我使用的代码是:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

答案 19 :(得分:0)

这对我有用:

RewriteCond %{HTTP_HOST} ^(?!www.domain.com).*$ [NC]
RewriteRule ^(.*)$  http://www.domain.com$1  [R=301,L]

我将前瞻模式(?!www.domain.com)用于在将所有域重定向到www子域时排除www子域,以避免Apache中的无限重定向循环。

答案 20 :(得分:0)

要在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无重定向

答案 21 :(得分:-1)

我在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]

答案 22 :(得分:-1)

如果使用具有不同<VirtualHost *:80> s的两个ServerName块的上述解决方案......

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / http://www.example.com/
</VirtualHost>
<VirtualHost *:80>
    ServerName www.example.com
</VirtualHost>

...然后你必须设置NameVirtualHost On

如果您不这样做,Apache不允许自己使用不同的ServerName来区分块,因此您收到以下错误消息:

[warn] _default_ VirtualHost overlap on port 80, the first has precedence

...要么没有重定向,要么你有一个无限的重定向循环,这取决于你先放入哪个块。

答案 23 :(得分:-2)

我发现在使用多个虚拟主机时使用ServerAlias更容易(也更有用)。

<VirtualHost x.x.x.x:80>
    ServerName www.example.com
    ServerAlias example.com
    ....
</VirtualHost>

这也适用于https vhosts。