使用 mod_rewrite 重定向不支持的语言代码
我正在开发一个多语言网站,并且我在 url 中使用语言标识符与前端控制器结合使用,以便访问
http://www.domain.tld/en/content
或
http://www.domain.tld/de/conent
提取以这些语言本地化的内容。如果访问该网站时未指定语言标识符,则通过 Accept-Language 检测用户浏览器的语言设置作为最佳猜测,然后进行重定向。如果无法检测到 Accept-Language,则默认为英语。因此,例如,如果您访问
http://www.domain.tld/content
并且您的浏览器语言设置为德语,并且 Accept-Language 检测到 de,您将被重定向到
http://www.domain.tld/de/content
如果您的浏览器语言设置不受支持,您将被重定向到默认支持的语言英语
http://www.domain.tld/en/content
这工作正常...只要不要在 url 开头手动输入带有不受支持的语言标识符的 url。为了解释一下,我设置了 mod_rewrite,以便不指向现有文件或文件夹的 url 调用前端控制器。既然如此,如果我故意在浏览器中放入不支持的语言代码,例如“it”,
http://www.domain.tld/it/content
则会调用前端控制器,但我想避免这种情况,而是更喜欢让 Apache 过滤请求,以便仅支持支持的语言提供给前端控制器。
本质上,我想要的是能够定义一个规则,如果 url 不以受支持的语言标识符开头,则用户将被重定向到一个 url,该 url 将不支持的语言代码替换为默认语言代码 (en),而无需调用前控制器。
这是我的配置文件:
#
# Access rights and behaviours for DocumentRoot
#
<Directory /WWW>
#
Options +FollowSymLinks +Indexes -MultiViews
# Allow requests for all
Order allow,deny
Allow from all
# Don't use access rules defined in child directories
AllowOverride None
# Define the router as the default index page
DirectoryIndex /router.php
# Turn on url rewriting
RewriteEngine on
# If we encounter a request to document root and can detect a language preference, grab it...
RewriteCond %{HTTP:Accept-Language} ^(en|de|fr)[-,;]? [NC,OR]
# ... or use the default language identifier (english) ...
RewriteCond en ^(en)$
# ... and redirect the request to a path prefixed with the language identifier
RewriteRule ^$ /%1/ [R=301,L]
# Mystery rule here!
# If the requested file does not exist...
RewriteCond %{REQUEST_FILENAME} !-f
# ... or if the requested directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
# ...forward the request to the router
RewriteRule ^(.*)$ router.php/$1 [L]
</Directory>
我将“神秘规则放在这里!” comment 是我需要定义规则的地方,这样如果请求 uri 不以受支持的语言代码开头,则将使用 en 。
我尝试了多种方法来做到这一点,但总是陷入重定向循环。举例来说,我正在尝试做的事情
RewriteCond %{REQUEST_URI} !^/(en|de|fr).$
RewriteRule ^$ /en/$1 [R=301,L]
这应该代表的是:
如果请求 uri 不是以 en、de 或 fr 开头,则获取 uri 的其余部分,并以 en 为前缀,然后将前端控制器重定向到截距。
有人能给我建议吗?谢谢!
I'm developing a multilingual site, and I'm using language identifiers in urls in conjunction with a front controller such that visiting
http://www.domain.tld/en/content
or
http://www.domain.tld/de/conent
will pull up content localised in those languages. If the site is visited without specifying a language identifier, the users browsers language settings are detected via Accept-Language as a best guess, and then redirected. If Accept-Language cannot be detected, then it defaults to english. So, for example, if you visit
http://www.domain.tld/content
and your browsers language settings are in german and Accept-Language detects de, you'll be redirected to
http://www.domain.tld/de/content
If your browsers language settings are not supported, you'll be redirected to the default supported language, english
http://www.domain.tld/en/content
This works fine... as long as don't manually put in a url with an unsupported language identifier at the beginning of the url. To explain, I have mod_rewrite set up such that urls that dont point to existing files or folders invoke the front controller. That being the case, if I purposefully put in an unsupported language code in the browser, such as 'it',
http://www.domain.tld/it/content
The front controller is invoked, but I want to avoid this, instead prefering to have Apache filter requests such that only supported languages are provided to the front controller.
Essentially what I want is to be able to define a rule such that if a url does not start with a supported language identifier, that users will abe redirected to a url that replaces the unsupported language code with the default one (en) without invoking the front controller.
This is my config file:
#
# Access rights and behaviours for DocumentRoot
#
<Directory /WWW>
#
Options +FollowSymLinks +Indexes -MultiViews
# Allow requests for all
Order allow,deny
Allow from all
# Don't use access rules defined in child directories
AllowOverride None
# Define the router as the default index page
DirectoryIndex /router.php
# Turn on url rewriting
RewriteEngine on
# If we encounter a request to document root and can detect a language preference, grab it...
RewriteCond %{HTTP:Accept-Language} ^(en|de|fr)[-,;]? [NC,OR]
# ... or use the default language identifier (english) ...
RewriteCond en ^(en)$
# ... and redirect the request to a path prefixed with the language identifier
RewriteRule ^$ /%1/ [R=301,L]
# Mystery rule here!
# If the requested file does not exist...
RewriteCond %{REQUEST_FILENAME} !-f
# ... or if the requested directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
# ...forward the request to the router
RewriteRule ^(.*)$ router.php/$1 [L]
</Directory>
Where I've put the "Mystery rule here!" comment is where I need to define a rule such that if the request uri does not begin with a supported language code, that en will be used in place.
I've tried doing this a number of ways, but keep falling into redirect loops. To example what I'm trying to do
RewriteCond %{REQUEST_URI} !^/(en|de|fr).$
RewriteRule ^$ /en/$1 [R=301,L]
What this is supposed to represent is:
If the request uri does not begin with en, de or fr, grab the remainder of the uri, prefix it with en, then redirect for the front controller to intercept.
Can anyone advise me? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试此规则:
如果 URI 路径尚未以
/en
、/de
开头,则会在 URI 路径的开头添加/en
,或/fr
。Try this rule:
This will add
/en
at the begin of the URI path if it does not already start with either/en
,/de
, or/fr
.