我有一个网站(Flash)本地化成十几种语言,我想根据用户的浏览器设置自动定义一个默认值,以尽量减少访问内容的步骤。
仅供参考,由于代理限制,我不能使用服务器脚本,所以我猜JavaScript或ActionScript将适合解决这个问题。
问题:
有其他的解决办法或建议吗?
这篇文章表示浏览器的导航器对象的以下属性:
navigator.language
navigator.browserLanguage
navigator.systemLanguage
navigator.userLanguage
将这些转换成javascript函数,在大多数情况下,您应该能够猜出正确的语言。确保优雅地降级,所以有一个包含语言选择链接的div,这样如果没有javascript或方法不起作用,用户仍然可以决定。如果它起作用了,就隐藏div。
在客户端这样做的唯一问题是,要么你将所有语言提供给客户端,要么你必须等到脚本运行并检测到语言后才能请求正确的版本。也许将最流行的语言版本作为默认设置会激怒最少的人。
编辑:我赞同Ivan的cookie建议,但要确保用户以后可以随时更改语言;不是每个人都喜欢浏览器默认的语言。
正确的方法是查看发送到服务器的HTTP 接收语言报头。这包含用户配置浏览器首选的有序、加权的语言列表。
不幸的是,这个头文件不能在JavaScript中读取;所有你得到的是navigator.language,它告诉你安装了哪个本地化版本的浏览器。这与用户的首选语言不一定是一回事。在IE上,你会得到systemLanguage(操作系统安装语言),browserLanguage(与language相同)和userLanguage(用户配置的操作系统区域),这些都同样没有帮助。
systemLanguage
browserLanguage
language
userLanguage
如果我必须在这些属性中做出选择,我将首先嗅探userLanguage,返回到language,然后(如果它们不匹配任何可用的语言)再查看browserLanguage,最后查看systemLanguage。
如果你可以把一个服务器端脚本放在网络上的其他地方,它只是读取Accept-Language报头,并将其作为JavaScript文件返回,报头值在字符串中,例如:
var acceptLanguage= 'en-gb,en;q=0.7,de;q=0.3';
然后你可以在HTML中包含一个指向外部服务的脚本src>,并使用JavaScript来解析语言头。不过,我不知道有任何现有的库代码可以做到这一点,因为Accept-Language解析几乎总是在服务器端完成。
无论你最终做什么,你肯定需要一个用户覆盖,因为它总是会猜错一些人。通常把语言设置放在URL中是最简单的。http://www.example.com/en/site vs http://www.example.com/de/site),并让用户单击两者之间的链接。有时,您确实希望两种语言版本都有一个URL,在这种情况下,您必须将设置存储在cookie中,但这可能会使不支持cookie和搜索引擎的用户代理感到困惑。
你说你的网站有Flash,那么,作为另一种选择,你可以通过flash.system.Capabilities.language&mdash获得操作系统的语言;查看如何确定浏览器内的操作系统语言到猜一猜操作系统区域设置。
flash.system.Capabilities.language
在Chrome和Firefox 32+上,Navigator.languages包含一个按照用户偏好顺序排列的区域设置数组,并且比navigator.language更准确,然而,为了使其向后兼容(已测试的Chrome / IE / Firefox / Safari),然后使用:
Navigator.languages
function getLang() { if (navigator.languages != undefined) return navigator.languages[0]; return navigator.language; }
关于这个,我做了一些研究。到目前为止,我已将我的发现总结在下表中
所以推荐的解决方案是写一个服务器端脚本来解析Accept-Language头文件。传递给客户端,用于设置网站语言。奇怪的是,为什么需要服务器来检测客户端的语言偏好,但这就是目前的情况。还有其他各种各样的黑客可以检测语言,但根据我的理解,读取Accept-Language头是推荐的解决方案。
Accept-Language
结合浏览器用来存储用户语言的多种方式,你得到这个函数:
const getNavigatorLanguage = () => { if (navigator.languages && navigator.languages.length) { return navigator.languages[0]; } else { return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'; } }
navigator.languages
'en'
下面是性感的俏皮话:
const getNavigatorLanguage = () => (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
您还可以尝试从文档中获取语言,这可能是您的第一个调用端口,然后返回到其他方法,因为人们经常希望他们的JS语言与文档语言匹配。
HTML5:
document.querySelector('html').getAttribute('lang')
遗留问题:
document.querySelector('meta[http-equiv=content-language]').getAttribute('content')
没有真正的资源是100%可靠的,因为人们可能只是把它放在错误的语言中。
有一些语言检测库可以让您根据内容确定语言。
用户的首选语言和系统/浏览器区域之间存在差异。
用户可以在浏览器中配置首选语言,这些语言将用于navigator.language(s),并在从服务器请求资源时使用,根据语言优先级列表请求内容。
navigator.language(s)
但是,浏览器的语言环境将决定如何呈现数字、日期、时间和货币。这种设置可能是排名最高的语言,但不能保证。在Mac和Linux上,语言环境由系统决定,而不考虑用户的语言首选项。在Windows上,可以在Chrome上的首选列表中选择语言。
通过使用Intl (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl),开发人员可以覆盖/设置用于呈现这些内容的区域设置,但有些元素是不能被覆盖的,例如<input type="date">格式。
<input type="date">
要正确地提取这种语言,我找到的唯一方法是:
(new Intl.NumberFormat()).resolvedOptions().locale
(Intl.NumberFormat().resolvedOptions().locale似乎也工作)
Intl.NumberFormat().resolvedOptions().locale
这将为默认区域设置创建一个新的NumberFormat实例,然后读入那些已解析选项的区域设置。
我使用了所有的答案,并创建了一个单行解决方案:
const getLanguage = () => navigator.userLanguage || (navigator.languages && navigator.languages.length && navigator.languages[0]) || navigator.language || navigator.browserLanguage || navigator.systemLanguage || 'en'; console.log(getLanguage());