如何使用 Apache / mod_rewrite 基于 Accept-Language 重定向

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1661915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 18:21:27  来源:igfitidea点击:

How to redirect based on Accept-Language with Apache / mod_rewrite

phpapache.htaccessmod-rewriteredirect

提问by meleyal

For language redirects we currently create folders in the web root containing an index.php file which checks the HTTP_ACCEPT_LANGUAGEserver variable. e.g. for the url www.example.com/press/

对于语言重定向,我们目前在 Web 根目录中创建文件夹,其中包含检查HTTP_ACCEPT_LANGUAGE服务器变量的 index.php 文件。例如对于网址www.example.com/press/

in /var/www/site/press/index.php:

/var/www/site/press/index.php

<?php
  if ($_SERVER["HTTP_ACCEPT_LANGUAGE"] == "en")
    header("location: ../press_en.php");
  else 
    header("location: ../press_de.php");
?>

As the site has grown, we now have many such folders. I am trying to clean this up by moving the redirects to a single .htaccess file:

随着网站的发展,我们现在有很多这样的文件夹。我试图通过将重定向移动到单个 .htaccess 文件来清理它:

RewriteEngine on

# Set the base path here
RewriteBase /path/to/site/

# The 'Accept-Language' header starts with 'en'
RewriteCond %{HTTP:Accept-Language} (^en) [NC]

# EN redirects
RewriteRule press(/?)$   press_en.php [L,R]

# DE redirects (for all languages not EN)
RewriteRule press(/?)$   press_de.php [L,R]

The idea is the same as the php file, but it doesn't work. I have tried all the possible language settings / orders in Firefox preferences, and checked the headers are correct, but it always serves the press_de.phpfile.

思路和php文件一样,但是不行。我已经在 Firefox 首选项中尝试了所有可能的语言设置/顺序,并检查了标题是否正确,但它始终为press_de.php文件提供服务。

What am I doing wrong, or is there a better way? (not including content negotiation / multiviews or anything that requires renaming files, this is not currently an option).

我做错了什么,还是有更好的方法?(不包括内容协商/多视图或任何需要重命名文件的内容,目前这不是一个选项)

回答by Gumbo

I would put the language indicator at the start of the URL path like /en/…or /de/…. Then you can use a single script that checks the preferred language and redirects the request by prepending the language indicator:

我会将语言指示符放在 URL 路径的开头,例如/en/…/de/…。然后,您可以使用单个脚本来检查首选语言并通过添加语言指示符来重定向请求:

// negotiate-language.php
$availableLanguages = array('en', 'de');
if (!preg_match('~^/[a-z]{2}/~', $_SERVER['REQUEST_URI'])) {
    $preferedLanguage = someFunctionToDeterminThePreferedLanguage();
    if (in_array($preferedLanguage, $availableLanguages)) {
        header('Location: http://example.com/'.$preferedLanguage.$_SERVER['REQUEST_URI']);
    } else {
        // language negotiation failed!
        header($_SERVER['SERVER_PROTOCOL'].' 300 Multiple Choices', true, 300);
        // send a document with a list of the available language representations of REQUEST_URI
    }
    exit;
}

And the corresponding rules:

以及相应的规则:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ negotiate-language.php [L]
RewriteRule ^([a-z]{2})/([^/]+)$ _.php [L]

Note that you need a proper someFunctionToDeterminThePreferedLanguagefunction as Accept-Languageheader fieldis not a single value but a list of qualified values. So there might be more than just one value and the first value is not always the prefered value.

请注意,您需要一个适当的someFunctionToDeterminThePreferedLanguage功能,因为Accept-Language标头字段不是单个值,而是一个限定值列表。所以可能不止一个值,第一个值并不总是首选值。

回答by Vladimir Ch

in htaccess

在 htaccess 中

RewriteEngine on
RewriteCond %{HTTP:Accept-Language} (en) [NC]
RewriteRule .* server.com/press_en.php [L]


RewriteCond %{HTTP:Accept-Language} (de) [NC]
RewriteRule .* server.com/press_de.php [L]