使用 mod_rewrite 重定向不支持的语言代码

发布于 2024-09-12 11:32:18 字数 2459 浏览 0 评论 0原文

我正在开发一个多语言网站,并且我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忱杏 2024-09-19 11:32:18

尝试此规则:

RewriteRule !^(en|de|fr)/ /en%{REQUEST_URI} [R=301,L]

如果 URI 路径尚未以 /en/de 开头,则会在 URI 路径的开头添加 /en ,或/fr

Try this rule:

RewriteRule !^(en|de|fr)/ /en%{REQUEST_URI} [R=301,L]

This will add /en at the begin of the URI path if it does not already start with either /en, /de, or /fr.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文