12

例如,如果用户将浏览器设置为 fr-CA,但我的网站可以选择以另一种可用语言(如英语)查看页面。如何覆盖接受语言标头,以便可以使用指定的语言重新加载?

我试图简单地更改 Accept-Language 标题,然后重新加载页面,但我不确定如何执行此操作。有什么想法吗?

更新:好的,所以我让人们向我解释什么是本地化,所以我一定没有正确地问这个问题。

我的网站目前在 web.config 中将全球化设置为自动,因此它会自动将线程文化设置为在应用程序启动时协商的任何语言。默认情况下,用户的浏览器将根据浏览器的语言设置发送接受语言标头,就像下面有人指出的那样,普通用户不知道它们是什么,它们在哪里,或者如何更改它们。在任何情况下,让我们将此默认行为称为浏览器将首先处理语言标头。但是,作为一项功能,我希望允许用户从页面更改此接受语言标题。例如,在应用程序中,语言设置通常由 cookie 或用户偏好(通过配置文件设置)确定,但在登录/登录页面上(特别是如果这是您第一次在某台计算机上登录),我不知道你是谁,所以我只能关闭你的浏览器设置。但是,假设您正在出差并从美国计算机访问此站点,页面以英文加载,您无法阅读,并且您不知道如何更改浏览器语言。可以从下拉菜单或图标或其他东西中选择您的语言不是很好吗?我想会的。

因此,为了做到这一点,我需要能够更改接受语言标题并重新加载页面。这是我不知道如何进行的地方。

我试过了navigator.language = <selected language>xhr.setRequestHeader但这些似乎不起作用。

4

2 回答 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 日期,则将使用英语约定进行解析,所以浮点数会。

IE:如果浏览器设置为 en_US 的美国用户选择使用您的应用程序的西班牙语界面,则当此用户将信息发布到服务器时,日期如下:

1/5/2015 将在服务器中解析为 1 月 5 日,而不是 5 月 1 日。

像 1,900 这样的数字将在服务器中被解析为 1900 而不是 1.900。

我经过惨痛的教训才学到这个。我在这里有一个从未回答过的问题。

请让我知道,如果你有任何问题。

于 2013-08-30T00:52:52.977 回答
6

Accept-Languageheader是一个请求头,所以是浏览器(或者其他客户端软件)发送的。在您的服务器上,您可以无所事事地忽略它。也就是说,它本身没有效果;一切都取决于您的服务器端代码是否识别它并采取一些措施。因此,您不能也不需要更改浏览器发送的标头。

用户可以Accept-Language使用浏览器的首选项设置更改浏览器发送的标头。例如,在 Chrome 中,转到“设置”,单击“显示高级设置...”,向下滚动到“语言”,单击“语言和输入设置...”,然后添加语言并拖动以对其进行排序.

这不是人们经常做的事情,大多数人都不知道这种设置的存在。所以浏览器发送的通常是一些出厂默认值。它们可能很奇怪,例如Accept-Language: fr-CA,通过协议意味着,“如果您,亲爱的服务器,有我请求的资源的不同语言版本,请给我加拿大法语;如果你没有它,我不在乎你给哪个版本”。这意味着,如果资源以通用法语(法语法语)或英语存在,则这些资源不会优先于斯瓦希里语或沃拉普克语版本。所以一个更明智的标题通常是Accept-Language: fr-CA, fr, en,这在实践中你应该如何处理Accept-Language: fr-CA

于 2013-08-30T07:10:21.113 回答