如何更改浏览器的接受语言设置

12
如果用户将浏览器设置为 fr-CA,而我的网站提供了在其他可用语言(例如英语)中查看页面的选项。 我怎样才能覆盖 accept-language 标头以便我可以使用指定的语言重新加载?
我试图简单地更改 Accept-Language 标头,然后重新加载页面,但是我不确定如何做到这一点。 有什么想法吗?
更新: 好吧,我得到了一些人向我解释本地化是什么,所以我可能没有正确提问。
我的网站当前在 web.config 中设置为自动全球化,因此它将自动将线程文化设置为在应用程序启动时协商的任何语言。 默认情况下,用户的浏览器将基于浏览器的语言设置发送 accept-language 标头,就像下面有人指出的那样,普通用户不知道这些设置在哪里,如何更改这些设置。 无论如何,让我们称之为浏览器将首先处理语言标头的默认行为。 然而,作为一项功能,我想允许用户从页面更改此 accept-language 标头。 例如,在应用程序中,语言设置通常将通过 cookie 或用户首选项(通过配置文件设置)确定,但是在登录/登陆页上(特别是如果这是在某台计算机上第一次登录),我不知道您是谁,因此我只能使用浏览器设置。 但是假设您在出差并从美国计算机访问此网站,则页面将以英语加载,您无法阅读它,并且不知道如何更改浏览器语言,那么有选择从下拉菜单或图标中选择语言的选项不好吗? 我认为这很不错。
因此,为了实现这一点,我需要能够更改 accept-language 标头并重新加载页面。 这就是我不确定如何继续的地方。
我尝试过 navigator.language = 和 xhr.setRequestHeader,但似乎都不起作用。

不知道是否有帮助,但我使用Accept-Language来提供相关内容,并在服务器上没有可用的区域设置时提供备用方案。 - Bernhard
2个回答

7
我可能错了,但区域设置不是您在代码中更改的内容。这取决于浏览器用户配置。如果您正在使用HttpClient,则可以向服务器发送您想要的Accept-Language标头值,但不要期望从您的代码更改此设置并使其在浏览器中发起的所有请求中生效。
通常做法是使用自定义cookie设置用户语言首选项。默认情况下,您应该使用Accept-Language标头上的值填充此cookie。在ASP.NET MVC中,有一个设置,以便Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture根据用户的浏览器配置进行设置。
<system.web>
    <globalization enableClientBasedCulture="true" uiCulture="auto" culture="auto" />
</system.web>

你可以创建一个ActionFilter来检查自定义语言cookie,并相应地设置Thread.CurrentThread.CurrentUICulture。
Thread.CurrentThread.CurrentUICulture用于确定代码应使用哪些资源。而Thread.CurrentThread.CurrentCulture用于所有数字和日期处理。
以下是该操作筛选器的示例:
public class LanguageActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var langCookie = GetOrSetLanguageCookie(filterContext.HttpContext);
        var culture = new CultureInfo(langCookie.Value);

        Thread.CurrentThread.CurrentUICulture = culture;
    }

    private HttpCookie GetOrSetLanguageCookie(HttpContextBase context)
    {
        var cookie = context.Request.Cookies[Constants.LanguageCookieName];
        if (cookie == null)
        {
            //set the cookie for first time
            cookie = new HttpCookie(Constants.LanguageCookieName, Thread.CurrentThread.CurrentUICulture.Name)
            {
                Expires = DateTime.Now.AddYears(1),
                Path = "/"
            };
            context.Response.Cookies.Add(cookie);
        }
        return cookie;
    }
}

请注意: 即使您的用户在界面中选择了“es-Ar”,并且您相应地为该用户设置了UICulture,如果用户的浏览器配置为en-US日期,则以英文约定解析发布给该用户的日期,因此浮点数也将如此。 例如:如果在美国使用浏览器设置为en_US的用户选择使用您应用程序的西班牙语界面,当此用户向服务器发布信息时,如1/5/2015的日期将被解析为1月5日而不是5月1日。 如1,900这样的数字将被解析为1900而不是1.900。 我曾经吃过亏,这里有一个问题here从未得到答复。 如果您有任何问题,请让我知道。

好的,这就是我的网站实际上是如何设置的,使用web.config中的自动区域设置。我之所以使用它,是因为它会处理语言优先级列表。但我的问题是如何覆盖它。默认情况下,浏览器发送这些语言标头,我的网站会尽力遵守它们。我想覆盖浏览器发送的内容,以便允许用户手动选择,如果他们愿意作为一个功能。 - Sinaesthetic
顺便说一句,我知道如何在jquery中更改ajax调用的内容,但我真的需要一种通过post back来实现它的方法。即“更改标题并重新加载此页面。” - Sinaesthetic
我在开头几行回答了你的问题;如果我过于详细,对不起,我认为这对于你没有完整的图片会有所帮助。你不能在代码中更改这个。你肯定可以更改你的代码发起请求的标头,但你无法全局地更改它,以便浏览器中发起的每个后续请求现在都具有适当的标头,考虑到用户语言选择。 - Raciel R.
尝试从web.config中删除设置,当用户尚未选择时,使用Accept-Language作为默认设置。 我有点困惑现在。由于 web.config 设置的缘故,您的文化是基于 Accept-Language 设置的,无论您在过滤器上做什么。 但是这似乎只发生在 CurrentCulture 上,否则您将会在屏幕上看到错误的语言,而事实并非如此(至少在我的情况下不是)。 - Raciel R.
1
好的,看起来我当时的假设是准确的 :) 请记住,CurrentCulture和CurrentUICulture之间有区别,而且我所阅读的所有内容都只建议更改后者。 - Raciel R.
显示剩余6条评论

6
Accept-Language 头部是一个请求头,因此它由浏览器 (或其他客户端软件) 发送。在您的服务器上,您可以通过不做任何操作来忽略它。也就是说,它本身没有影响;一切取决于您的服务器端代码是否识别它并采取某些行动。因此,您不能也不需要更改浏览器发送的头部。
用户可以使用浏览器的首选项设置更改浏览器发送的 Accept-Language 头部。例如,在 Chrome 中,转到“设置”,点击“显示高级设置...”,滚动到“语言”,点击“语言和输入设置...”,然后添加语言并拖动以排序。
这不是人们经常做的事情,大多数人甚至不知道这样的设置存在。所以浏览器发送的通常是一些工厂默认值。它们可能相当奇怪,例如,Accept-Language: fr-CA 意味着,“如果你,亲爱的服务器,有我请求的资源的不同语言版本,请给我加拿大法语;如果你没有,那么我不关心你提供哪个版本”。这意味着,如果资源存在于通用法语 (法国法语) 或英语中,这些版本将不会优先于斯瓦希里语或沃拉普克语版本。因此,更明智的头部通常是 Accept-Language: fr-CA, fr, en,这也是您处理 Accept-Language: fr-CA 的实践方式。

1
“所以您无需更改浏览器发送的标头” - 是的,您可以更改。 - Martin Hetfield Mali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接