13

我在设置我的 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/

所以我的问题是:我如何让语言 URL 相对于它在我的开发服务器上的目录正常工作,然后理想情况下在没有任何环境特定规则的情况下运行时工作。

额外的问题:我是否需要在所有后续重写规则前面添加 ([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/,有什么想法吗?

4

2 回答 2

16

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

通过 htaccess 规则多语言进行无休止的重定向循环

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]
于 2013-11-11T09:30:52.073 回答
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标记为您的开发实时服务器的基本目录。

如果您尝试在同一开发主机上对项目进行版本控制或测试多个项目,则必须将命名方案合并到域名中,而不是 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>

最重要的是,除非您采用if-else mumbo jumbo 的mod-rewrite方式,否则您不能让相同的.htaccess文件规则在不同的部署目录中原封不动地工作,一旦您上线,它就会变得混乱。

为了让规则透明地工作,Apache 必须只查看并应用关于正在运行的内容(目录之后的内容)的规则,这就是转变这里对我们所做的事情/devX/projectX/DocumentRoot

如果对 .htaccess 的最小修改是可以的

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

因此,如果您继续RewriteBase /live将其更改为RewriteBase /devX/projectX/for development,则您的大多数RewriteRules 应该按原样工作。所以,/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

您正确地假设所有后续规则都需要此正则表达式,否则它们将无法匹配。所以,你的RewriteRuleforcasestudies不会工作。一种不关心语言前缀的更简单方法是将^URL 路径锚的开头删除为

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对上面没有语言目录前缀的所有 URL 进行了重定向,/en/$1理想情况下应该是

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

否则,/en也会被重定向到/en/en.

于 2013-10-28T15:03:49.563 回答