一段时间以来,我一直在使用这样的东西来获取用户的国家(ISO-3166):
const region = navigator.language.split('-')[1]; // 'US'
我一直认为的字符串类似于,在en-US
中,国家将持有数组的第二位。
我认为这个假设是不正确的,。根据MDN文档,navigator.language
返回:“表示BCP 47中定义的语言版本的字符串。”读BCP 47,主语言子标记保证为第一个(例如'en'),但区域代码不一定是第二个子标记。可以有先于区域子标记的子标记并跟随区域子标记。
例如,"sr-Latn-RS"
是一个有效的BCP 47语言标记:
sr | Latn | RS
primary language | script subtag | region subtag
从navigator.language
返回的值是BCP 47的子集,仅包含语言和区域吗?或者,是否有一个库或regex通常用于从语言标记中提取区域子标记?
发布于 2016-09-01 17:52:27
在这里发现的Regex:https://github.com/gagle/node-bcp47/blob/master/lib/index.js
var re = /^(?:(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))$|^((?:[a-z]{2,3}(?:(?:-[a-z]{3}){1,3})?)|[a-z]{4}|[a-z]{5,8})(?:-([a-z]{4}))?(?:-([a-z]{2}|\d{3}))?((?:-(?:[\da-z]{5,8}|\d[\da-z]{3}))*)?((?:-[\da-wy-z](?:-[\da-z]{2,8})+)*)?(-x(?:-[\da-z]{1,8})+)?$|^(x(?:-[\da-z]{1,8})+)$/i;
let foo = re.exec('de-AT'); // German in Austria
let bar = re.exec('zh-Hans-CN'); // Simplified Chinese using Simplified script in mainland China
console.log(`region ${foo[5]}`); // 'region AT'
console.log(`region ${bar[5]}`); // 'region CN'
发布于 2016-09-01 11:36:24
您的解决方案基于错误的前提,即浏览器的语言标记可靠地匹配用户的国家。我已经把我的浏览器语言设置为德语,尽管我目前住在德国附近,而是在美国。
另外,例如在Chrome中,许多语言包不要求您指定区域修饰符。将Chrome显示语言设置为德语
提供以下语言标记:
> navigator.language
< "de"
根本没有区域标记,而且是一种相当通用的语言。
底线是,我的浏览器设置会导致语言标签de
,即使我住在美国。
确定用户位置的一种更准确和可能更可靠的方法是从与请求关联的IP地址派生出该地址。有许多服务提供这种服务。ip-api.com就是其中之一:
$.get("http://ip-api.com/json", function(response) {
console.log(response.country); // "United States"
console.log(response.countryCode); // "US"
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
发布于 2021-08-08 15:26:31
现在可以使用国际化API中的现场对象从区域设置标识符中提取该区域。
const { region } = new Intl.Locale('sr-Latn-RS') // region => 'RS'
请注意,这与Internet Explorer当前不兼容。
https://stackoverflow.com/questions/39213855
复制相似问题