自动redirect到子目录,并删除www

我想做两件事:将http://www.example.com (与www )redirect到http://example.com/fr (不含www ,AND子目录)

当然,我也希望http://example.comredirect到http://example.com/fr

我看到这个解决scheme:

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

但它会像疯了一样减慢我的网站(以后不可能加载页面)。我应该在上面的代码中修复什么?

这是我完整的代码

 Options +FollowSymLinks RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^index\.php$ - [L] RewriteCond %{HTTP_HOST} ^(www\.)?beastof\.com$ [NC] RewriteCond %{REQUEST_URI} /(.*) RewriteCond %{REQUEST_FILENAME} !-f RewriteRule !^fr(/|$) /fr/%1 [R=301,L] RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L] RewriteRule . index.php [L] 

(这是一个关于子目录的WordPress多站点。)

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

这些指令不会简单地将“ http://www.example.com ”redirect到http://example.com/fr 。 他们将http://www.example.com/<anything>redirect到http://www.example.com/fr/<anything>

但它像疯了一样减慢我的网站…

你发布的指令没有什么特别的错,但是…

我的猜测是,你链接到其他页面/资源没有/fr/path段。 然后导致每个页面视图有多个外部redirect – 这可能会减慢你的网站速度(尽pipe这是301redirect,所以应该由浏览器caching)。

如果是这种情况,那么你需要修复你的内部链接来包含这个/fr/path段。 或者,也许从这个redirect排除静态资源(如果URL仍然有效,没有/fr/path段)?

例如,要排除所有静态资源,请修改您的指令,如:

 RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC] RewriteCond %{REQUEST_URI} /(.*) RewriteCond %{REQUEST_FILENAME} !-f RewriteRule !^fr/ /fr/%1 [R=301,L] 

这现在将防止静态资源(物理文件)被redirect(无论是否仍然有效,我不知道)。

我也稍微优化了你的指令(没有什么会导致主要的加速)。 我已经移除了/fr/的否定检查到RewriteRule 模式 ,而不是使用RewriteCond指令。 RewriteRule 模式首先被处理,所以如果可以的话,最好包含你的第一个检查(否则每个 URL都会被处理)。 然后从条件中抓取URL(在RewriteRule replace中, %1而不是$1反向引用)。 如果没有明确需要,则不需要使用NCNOCASE )标志。


更新#1:

example.com/fr (最后没有斜线),redirect到example.com/fr/fr

要解决这个问题,你可以改变RewriteRule 模式来排除/fr或者一个启动 /fr/的URL的完全匹配,例如:

 RewriteRule !^fr(/|$) /fr/%1 [R=301,L] 

这现在将阻止example.com/fr被redirect。 (然而,这是一个有效的URL吗?你现在有两个URL: example.com/frexample.com/fr/可能访问相同的资源?)

这是我完整的代码

 : RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] : 

既然你已经把你的“完整的代码”添加到你的问题中,我已经看到你已经有了一个“exception”块(上面的3个指令),排除了静态资源被重写 – 只是它在错误的地方,现在你已经添加了上面的其他指令。

您应该将这3个指令直接RewriteBase指令的下面(即在顶部)。 尽pipe你需要从这里排除文档根目录 (通过改变^!^$ – 见下文),以便允许/被redirect到/fr/ – ,因为文档根目录也是一个目录。 然后你可以从上面的代码块( 在这个答案的第一部分 )中删除RewriteCond %{REQUEST_FILENAME} !-f指令。


更新#2所以,总之…

(已更新,在开始时包含非wwwredirect的规范www,这样可以简化后面检查HTTP_HOST 。)

 Options +FollowSymLinks RewriteEngine on RewriteBase / # Canonical www to non-www redirect RewriteCond %{HTTP_HOST} ^www\.(example\.com)$ [NC] RewriteRule (.*) http://%1/$1 [R=301,L] # Exception: Exclude files and directories (except the document root) RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule !^$ - [L] RewriteRule ^index\.php$ - [L] # Redirect all requests to /fr/ subdirectory RewriteCond %{HTTP_HOST} =example.com [NC] RewriteCond %{REQUEST_URI} /(.*) RewriteRule !^fr(/|$) /fr/%1 [R=301,L] RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L] RewriteRule . index.php [L]