写点什么

Accept-Language 是什么? 就在身边,你却没看见的“冷知识”系列(不定期偶遇)

用户头像
八苦-瞿昙
关注
发布于: 2020 年 12 月 02 日
Accept-Language是什么? 就在身边,你却没看见的“冷知识”系列(不定期偶遇)

你看不到我,我就只能坑你了

为什么突然偶遇这个知识点呢?

主要还是有同学说这千年不动的功能我浏览器没有问题,咋你的就有问题呢?不可能,不科学

实际上一看还真有问题,还是sql 报错了: 格式不支持,无法转化datetime

sql 实际传值成了 2020/11/28 上午 12:00:00

看代码传值写法:DateTime.ToString()

再比较请求差异:正确的请求 header 是 Accept-Language:en-us

异常的请求 header 是 Accept-Language:zh-cn

好家伙,原来小伙伴们不了解 Accept-Language是干啥的,就这样被坑了



Accept-Language是什么?

引用developer.mozilla.org专业解释(web方面,http等很多定义小伙伴们可以看它,很全面了)

Accept-Language 请求头允许客户端声明它可以理解的自然语言,以及优先选择的区域方言。借助内容协商机制,服务器可以从诸多备选项中选择一项进行应用, 并使用 Content-Language 应答头通知客户端它的选择。浏览器会基于其用户界面语言为这个请求头设置合适的值,即便是用户可以进行修改,但是这种情况极少发生(因为可增加指纹独特性,通常也不被鼓励)(译者注:通常只在测试网站的多语言支持时手动修改它;或为进一步减少指纹独特性,改为最常见的英文)。



当服务器无法通过其他方式来确定应当使用的语言时——例如某一特定的 URL,这是用户明确指定的——这个请求头可以用作提示。建议服务器端永远不要覆盖明确指定的信息。Accept-Language 消息头的内容通常不在用户的掌控之中(例如在国外旅行时到提供网络服务的场所上网);另外用户可能会想要浏览非本地用户界面语言的页面。



如果服务器不能提供任何可以匹配的语言的版本,那么理论上来说应该返回一个 406(Not Acceptable,不被接受)的错误码。但是为了更好的用户体验,这种方法很少被采用,取而代之的是将其忽略。



简单来说,就是 浏览器对api 说,用户有份能看懂的语言列表,api 你按照权重捡你有的给我。

这个是http 内容协商机制中针对自然语言的一个定义。

目前基本所有的浏览器都已支持,

所以大家注意一起浏览器的请求就会发现可能有类似的header,有没有取决大家的语言设置

当然网站支不支持就要看网站老板了,所以你看github 就不会给我一个中文页面,人家压根就没有



那么一般网站是如何用Accept-Language支持多语言的呢?

其实没什么特别做法,就是 Accept-Language 的值找到个可用的语言,切换自己程序的多语言设置,从而切换多语言资源就欧克了



为了方便大家理解,就举aspnet core 为例说明怎么影响多语言的

aspnet core 在启用多语言支持功能后在 RequestLocalizationMiddleware 会根据 AcceptLanguageHeaderRequestCultureProvider 修改当前线程语言设置,从而实现多语言切换



RequestLocalizationMiddleware 的逻辑

// 节选自 https://github.com/dotnet/aspnetcore/blob/94b1c6f6b423482ce52fb0473df33b6699ea755e/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs#L125
// 为了方便理解,有删减
public async Task Invoke(HttpContext context)
{
var requestCulture = _options.DefaultRequestCulture;
foreach (var provider in _options.RequestCultureProviders)
{
var providerResultCulture = await provider.DetermineProviderCultureResult(context);
var cultures = providerResultCulture.Cultures;
var uiCultures = providerResultCulture.UICultures;
var result = new RequestCulture(cultureInfo, uiCultureInfo);
requestCulture = result;
break;
}
CultureInfo.CurrentCulture = requestCulture.Culture;
CultureInfo.CurrentUICulture = requestCulture.UICulture;
await _next(context);
}



AcceptLanguageHeaderRequestCultureProvider 取值逻辑

// 节选自 https://github.com/dotnet/aspnetcore/blob/94b1c6f6b423482ce52fb0473df33b6699ea755e/src/Middleware/Localization/src/AcceptLanguageHeaderRequestCultureProvider.cs
public class AcceptLanguageHeaderRequestCultureProvider : RequestCultureProvider
{
/// <summary>
/// The maximum number of values in the Accept-Language header to attempt to create a <see cref="System.Globalization.CultureInfo"/>
/// from for the current request.
/// Defaults to <c>3</c>.
/// </summary>
public int MaximumAcceptLanguageHeaderValuesToTry { get; set; } = 3;
/// <inheritdoc />
public override Task<ProviderCultureResult?> DetermineProviderCultureResult(HttpContext httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
var acceptLanguageHeader = httpContext.Request.GetTypedHeaders().AcceptLanguage;
if (acceptLanguageHeader == null || acceptLanguageHeader.Count == 0)
{
return NullProviderCultureResult;
}
var languages = acceptLanguageHeader.AsEnumerable();
if (MaximumAcceptLanguageHeaderValuesToTry > 0)
{
// We take only the first configured number of languages from the header and then order those that we
// attempt to parse as a CultureInfo to mitigate potentially spinning CPU on lots of parse attempts.
languages = languages.Take(MaximumAcceptLanguageHeaderValuesToTry);
}
var orderedLanguages = languages.OrderByDescending(h => h, StringWithQualityHeaderValueComparer.QualityComparer)
.Select(x => x.Value).ToList();
if (orderedLanguages.Count > 0)
{
return Task.FromResult<ProviderCultureResult?>(new ProviderCultureResult(orderedLanguages));
}
return NullProviderCultureResult;
}
}



发布于: 2020 年 12 月 02 日阅读数: 101
用户头像

八苦-瞿昙

关注

一个假和尚,不懂人情世故。 2018.11.23 加入

会点点技术,能写些代码,只爱静静。 g hub: https://github.com/fs7744 黑历史:https://www.cnblogs.com/fs7744

评论 (2 条评论)

发布
用户头像
静静是谁?
2020 年 12 月 02 日 23:58
回复
静静是位常来我们小庙的香客,貌美如仙,惊为天人
2020 年 12 月 03 日 09:56
回复
没有更多了
Accept-Language是什么? 就在身边,你却没看见的“冷知识”系列(不定期偶遇)