我有一个网站,似乎不能从非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] 

我错过了什么?


使用重写引擎是解决这个问题的重量级方法。这里有一个更简单的解决方案:

<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指令时,Apache会自动保留/之后的所有内容,这是一个常见的误解,为什么这个方法不起作用(实际上它可以)。


试试这个:

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

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

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

This starts with the HTTP_HOST variable, which contains just the domain name portion of the incoming URL (example.com). Assuming the domain name does not contain a www. and matches your domain name exactly, then the RewriteRule comes into play. The pattern ^(.*)$ will match everything in the REQUEST_URI, which is the resource requested in the HTTP request (foo/blah/index.html). It stores this in a back reference, which is then used to rewrite the URL with the new domain name (one that starts with www).

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


要从你的URL网站中删除www,请在。htaccess文件中使用以下代码:

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

要在你的网站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。


我运行了这个…

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

我需要这是通用的25+域在我们的新服务器,所以这个指令是在我的virtual.conf文件在<Directory>标签。(dir是所有docroots的父目录)

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


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]

    <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的任何请求。

干杯!


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

<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

…或者没有重定向发生,或者有一个无限重定向循环,这取决于你先放哪个块。


我使用的代码是:

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

我也有同样的问题。 但是用这个解决了

RewriteEngine上 重写HTTP_HOST} ! RewriteRule ^ (. *) http://www.% {HTTP_HOST} / 1美元(R = 301 L)

将non-www重定向到www。

这个规则将www重定向到非www

RewriteEngine上 ^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/


我发现在使用多个vhost时使用ServerAlias更容易(也更有用)。

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

这也适用于https vhosts。


重定向域。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]

其他的子域仍在工作。 不需要调整线条。只需复制/粘贴到正确的位置。

如果你修改了vhost,不要忘记应用apache的变化。

(基于默认的Drupal7 .htaccess,但应该在很多情况下工作)


这与许多其他建议类似,只是做了一些增强:

不需要硬编码域(适用于接受多个域或环境之间的vhosts) 保留方案(http/https),忽略前面%{REQUEST_URI}规则的影响。 路径部分不受%{REQUEST_URI}等先前rewriterrules的影响。 重写HTTP_HOST} !(数控) RewriteRule ^(.*)$ %{ REQUEST_SCHEME}: / / www. % {HTTP_HOST} / 1美元(R = 301 L)


我在WP Multisite上有一个类似的任务,其中重定向规则必须是通用的(对于我添加到网络中的任何给定域)。我首先解决了向域(停放的域)添加通配符。注意。com之后。

CNAME * domain.com.

然后我在我的多站点根目录下的.htaccess文件中添加了以下代码行。我想它适用于任何网站。

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

希望这能有所帮助。

ps.如果你想从not www重定向到www,把最后一行改为

RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]

<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


如果你正在使用Apache 2.4,不需要启用重写Apache模块,你可以使用这样的东西:

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

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

检查这个完美的工作


这对我来说很管用:

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

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


重定向代码的非www => www和相反的www =>非www。在.htaccess文件中没有硬编码域和方案。因此,源域名和http/https版本将被保留。

Apache 2.4及更新版本

www => www:

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]

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


Apache 2.2及更新版本

www => 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 =>非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…


不要总是使用Redirect permanent(或者为什么将来会出现问题)

如果以后有机会添加子域,不要使用永久重定向。

因为如果客户端使用了一个没有注册为VirtualHost的子域,他可能永远也不会到达这个子域,即使后来注册了。

重定向永久发送一个HTTP 301永久移动到客户端(浏览器),他们中的许多人永远缓存这个响应(直到缓存被[手动]清除)。因此,使用该子域将始终自动重定向到www.***,而无需再次请求服务器。

请参阅浏览器缓存HTTP 301多长时间?

使用重定向

<VirtualHost *:80>
  ServerName example.com

  Redirect / http://www.example.com/
</VirtualHost>

Apache.org -何时不使用mod_rewrite

Apache.org -规范主机名


这很简单!

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

如果你有多个域名(可选)

-如果所有这些域名都使用https(因为他们应该)

-如果你想让所有的域名都使用www。domainName

这将避免doble重定向(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>

And

<VirtualHost *:443>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

您应该将重定向代码301更改为最方便的代码


要将所有直接发送到域名www的请求重定向到301,您可以使用:

RewriteEngine On

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

这样做的好处是,如果你有任何有效的子域,这将工作。

example.com重定向到www.example.com

没有重定向

没有重定向


如果你只想加载www的https版本,在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>

这是我自己网站的配置,工作起来很有魅力。

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