htaccess具有子目录的多语言站点,默认为301

时间:2013-10-24 15:45:39

标签: .htaccess localization multilingual http-status-code-301

我在设置htaccess时遇到一些问题,允许多种语言使用子目录方法,例如:

http://www.domain.com/en/
http://www.domain.com/sw/
http://www.domain.com/ie/

另外,为了使事情复杂化,该项目目前还没有,它在开发服务器上。例如,我目前正在访问该项目:

http://dev.domain.com/devname/projectname/

我希望以上自动301重定向到:

http://dev.domain.com/devname/projectname/en/

这是我的htaccess:

Options +FollowSymLinks -MultiViews
RewriteEngine on

# ----------------------------------------------------------------------
# MULTI LANGUAGE SUB DIRECTORY
# ----------------------------------------------------------------------

RewriteCond %{REQUEST_URI} !^/(en|sw)/
RewriteRule ^(.*)$ en/$1 [R=301,L]

# ----------------------------------------------------------------------
# Rewrite rules
# ----------------------------------------------------------------------

## CASE STUDIES ##
RewriteRule ^casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [L,QSA]

## PRODUCTS ##
RewriteRule ^products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [L,QSA]

RewriteRule ^([a-z{2}]+)(/)?$ index.php?controller=contents&method=viewHome&lang=$1 [L,QSA] # Default load
RewriteRule ^(/)?$ index.php?controller=contents&method=viewHome [L,QSA] # Default load

上述内容实际上会重定向到:

http://dev.domain.com/home/webserver_dir/devname/projectname/en/

..如果我使用RewriteBase,它似乎只是转到......

http://dev.domain.com/en/

所以我的问题:如何让语言网址相对于我的开发服务器上的目录正常工作,然后理想情况下,它会在没有任何环境特定规则的情况下生效。< / p>

加分问题:我是否需要在所有后续重写规则之前添加([az {2}] +)位,或者我可以捕获所有会影响所有其他规则的内容?

编辑-----------------------------

我已根据建议将其缩小为以下内容......

Options +FollowSymLinks -MultiViews
RewriteEngine on

RewriteBase /devname/projectname/

RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load

...但现在它重定向到http://dev.domain.com/devname/projectname/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/,有什么想法吗?

2 个答案:

答案 0 :(得分:14)

您是否尝试过以下链接中的答案?它应该做你想要实现的目标。

Endless Redirect Loop by htaccess rules multi language

RewriteEngine On
RewriteBase /   

# empty url -> redirect to en/
RewriteCond %{QUERY_STRING} !lang=(en|de)
RewriteRule ^$ en/ [R=301,L]

# url is ONLY '/en' or '/de' -> redirect to /en/ or /de/ (adding slash)
RewriteRule ^(en|de)$  $1/ [R=301,L]

# now all urls have en/ de/ -> parse them
RewriteRule ^(en|de)/(.*)$  $2?lang=$1&%{query_STRING} [L]

答案 1 :(得分:4)

如果.htaccess不得更改

DEV 服务器项目的<VirtualHost>配置更改为

<VirtualHost *:80>
    ServerName dev.domain.com
    ServerAlias project.domain.com
    DocumentRoot "/home/webserver_dir/devname/projectname"
</VirtualHost>

这些更改通常会在您的 httpd-vhosts.conf 文件中。您的 .htaccess 文件现在有

RewriteBase /

root 标记为开发 live 服务器的 base 目录。

如果您尝试在同一 dev 主机上对项目进行版本测试或测试多个项目,则必须将命名方案合并到域名而不是URL路径中。例如,

<VirtualHost *:80>
    ServerName dev1.domain.com
    ServerAlias project1.domain.com
    DocumentRoot "/home/webserver_dir/dev1/project1"
</VirtualHost>

<VirtualHost *:80>
    ServerName dev2.domain.com
    ServerAlias project2.domain.com
    DocumentRoot "/home/webserver_dir/dev2/project2"
</VirtualHost>

最重要的是,除非您采用 mod-rewrite 的方式,否则不能使用相同的 .htaccess 文件规则。 if-else mumbo jumbo,一旦你上线就会加入混乱。

为了使规则透明地工作,Apache必须只查看和应用关于 live /devX/projectX/目录之后的内容)的规则,这就是转移DocumentRoot为我们做了这件事。

如果.htaccess的最小mod可以

并非每个人都可以访问Apache的 .conf 文件。某些主机正确拒绝修改它们的请求。这就是为什么,如果他们至少保持启用 mod-rewrite ,很多网站的设置都可以修改。其中之一是使用RewriteBase来处理不同的部署目录。

因此,如果您将RewriteBase /保留在 live 上,但将其更改为RewriteBase /devX/projectX/以进行开发,则大多数RewriteRule s应该按原样运作。因此,/devname/projectname/应该正确地重定向到/devname/projectname/en/

<小时/> 您对([a-z{2}]+)的使用不正确。您可能意味着([a-z]{2})准确捕获两个字母。如果您打算捕获两个或更多,它将变为([a-z]{2,})。因此,您的默认加载重写将变为

RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load

您可以假设您需要此正则表达式用于所有后续规则,否则它们将无法匹配。因此,RewriteRule的{​​{1}}无法正常工作。不关心语言前缀的一种简单方法是将URL路径锚点的casestudies开头删除为

^

您的上次RewriteRule /casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [NC,L,QSA] RewriteRule /products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [NC,L,QSA] 匹配RewriteRule并不是必需的,因为您已经为^(/)?$重定向所有没有语言目录前缀的网址301上面,理想情况下应该是

/en/$1

否则,RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC] RewriteRule ^(.*)$ en/$1 [R=301,L] 也会被重定向到/en