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&lt;VirtualHost&gt; 部分,用于您的真实服务器配置。当使用Redirect directive 时,Apache 会自动保留/ 之后的任何内容,这是一个常见的误解,即为什么这种方法不起作用(实际上它起作用)。

【讨论】:

对于一个也有 ssl 虚拟主机的网站,你如何做到这一点? 我在使用此建议时收到错误消息“example.com 上的网页导致重定向过多”。其他人有这个问题吗? @BlackDivine:反之亦然。只需将 www.exampleexample 交换到示例中的任何位置即可。 @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 规则的影响。

不受之前RewriteRules 影响的路径部分如%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 文件中的 标记中。 (dir 是所有 docroot 的父级)

尽管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】:

如果使用上述两个&lt;VirtualHost *:80&gt;块的解决方案不同ServerNames...

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

...那么您也必须设置NameVirtualHost On

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

[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的主要内容,如果未能解决你的问题,请参考以下文章

使用www从非www http重定向到https

从非www重定向到www

如何在 aws s3 存储桶和云端执行从非 www 到 www 的 301 重定向

Cloudflare从非主域重定向到Github页面

apache将http重定向到https,将www重定向到非www

Nginx 重定向(非 www 到 www)不适用于 Certbot