Tarayıcıda kullanıcının yerel ayarını belirlemenin en iyi yolu


204

Bir düzine dile yerelleştirilmiş bir web sitem (Flash) var ve içeriğe erişim adımlarını en aza indirmek için kullanıcının tarayıcı ayarlarına bağlı olarak varsayılan bir değeri otomatik olarak tanımlamak istiyorum.

Bilginize, proxy kısıtlamaları nedeniyle sunucu komut dosyalarını kullanamıyorum, bu yüzden JavaScript veya ActionScript'in sorunu çözmek için uygun olacağını düşünüyorum.

Sorular:

  1. Kullanıcının yerel ayarını 'tahmin etmek' için en iyi yöntem hangisidir?

  2. Bana yardımcı olabilecek mevcut basit sınıflar / işlevler var mı (karmaşık yerelleştirme paketleri yok)? Özellikle tüm olası dilleri daha akıllı bir şekilde daha küçük bir sayıya (çevirilerim) bölmek.

  3. Böyle bir çözüme hangi noktaya güvenebilirim?

  4. Başka geçici çözüm veya öneriniz var mı?


Bir tarayıcının kullanıcısıyla ilgili meta verilerini paylaşabilmesinin tek yolu URL ve üstbilgilerdir. Firefox'u alın ve bir istek yapıldığında gönderilen başlıklara bir göz atın. Tipik istek ve yanıt başlıklarını incelemek oldukça ilginçtir.
mP.

Yanıtlar:


188

Doğru yol, sunucuya gönderilen HTTP Accept-Language üstbilgisine bakmaktır . Bu, kullanıcının tarayıcılarını tercih edecek şekilde yapılandırdığı sıralı, ağırlıklı dil listesini içerir.

Ne yazık ki bu başlık JavaScript içinde okunamıyor; elde navigator.languageettiğiniz tek şey, web tarayıcısının hangi yerelleştirilmiş sürümünün yüklü olduğunu söyler. Bu, kullanıcının tercih ettiği dil (ler) ile aynı şey değildir. Bunun yerine IE'de systemLanguage(işletim sistemi yüklü dili), browserLanguage(ile aynı language) ve userLanguage(kullanıcı tarafından yapılandırılmış işletim sistemi bölgesi) elde edersiniz .

Bu özellikler arasında seçim yapmak zorunda kalsaydım, userLanguageilk önce kokladım languageve geriye ve sadece bundan sonra (mevcut herhangi bir dille eşleşmediyse) browserLanguageve sonunda baktım systemLanguage.

Net üzerinde Accept-Language üstbilgisini okuyan ve üstbilgi değeri dizede olan bir JavaScript dosyası olarak dağıtan başka bir yere sunucu tarafı komut dosyası koyabilirseniz, örn .:

var acceptLanguage= 'en-gb,en;q=0.7,de;q=0.3';

HTML'deki harici hizmeti işaret eden bir <script src> ekleyebilir ve dil başlığını ayrıştırmak için JavaScript kullanabilirsiniz. Accept-Language ayrıştırma hemen hemen her zaman sunucu tarafında yapıldığından, bunu yapmak için herhangi bir kütüphane kodu bilmiyorum.

Sonunda ne yaparsanız yapın, kesinlikle bir kullanıcı geçersiz kılmanız gerekir, çünkü bazı insanlar için her zaman yanlış tahmin eder. Genellikle dil ayarını URL'ye koymak (örneğin, http: //www.example.com/tr/site vs http: //www.example.com/de/site) ve kullanıcının tıklamasına izin vermek en kolay yoldur. ikisi arasındaki bağlantılar. Bazen her iki dil sürümü için tek bir URL istersiniz, bu durumda ayarı çerezlerde saklamanız gerekir, ancak bu kullanıcı aracılarını çerezler ve arama motorları desteği olmadan karıştırabilir.


11
MDN developer.mozilla.org/tr-TR/docs/Web/API/NavigatorLanguage/… "Kullanıcının tarayıcısından gelen her HTTP isteğindeki Accept-Language HTTP üstbilgisi, navigator.languages ​​özelliği için ekstra değer dışında aynı değeri kullanır q değerleri (kalite değerleri) alanı (ör. en-US; q = 0,8). "
S Meaden

3
Güncelleme: Artık (2020) tüm modern tarayıcılar tarafından desteklenen ve bir dizi dil tercihi döndüren deneysel bir özellik var: navigator.languages //["en-US", "zh-CN", "ja-JP"]Bu, 2020'de tarayıcıların en az% 95'inde çalışmalıdır.
Cornelius Roemer

1
navigator.languages, Her ikisine göre MDN'yi ve caniuse.com , şimdi tüm büyük tarayıcılarda kullanılabilir - minik (~ 200 bayt) deneyin gezgini-diller en modern ve geriye doğru uyumlu bir yaklaşım için paket.
mindplay.dk

86

Chrome ve Firefox 32+ sürümünde, navigator.languages, kullanıcı tercihi sırasına göre bir dizi yerel ayar içerir ve navigator.language'den daha doğrudur, ancak geriye doğru uyumlu hale getirmek için (Test edilmiş Chrome / IE / Firefox / Safari) kullanın. bu:

function getLang()
{
 if (navigator.languages != undefined) 
 return navigator.languages[0]; 
 else 
 return navigator.language;
}

2
IE9 ve IE10 için çalışmaz. Onlar için navigator.browserLanguage'i incelemeniz gerekiyor.
user393274 18:16

2
OneLiner:function getLang(){ return ( navigator.language || navigator.languages[0] ); }
JorgeGarza

4
@ChStark Olmamalı mı return navigator.languages[0] || navigator.language;?
James_

23
Ayrıca, doğru "one-liner" şu şekilde görünecektir: return (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.language;. Aksi takdirde navigator.languages, tanımsız veya boşsa bir istisna alırsınız .
Max Truxa

Daha da kompakt bir sürüm içinconst getLang = () => navigator.language || navigator.browserLanguage || ( navigator.languages || [ "en" ] ) [ 0 ]
João Miguel Brandão

41

Bu makalede , tarayıcının gezgin nesnesinin aşağıdaki özellikleri önerilmektedir :

  • navigator.language (Netscape - Tarayıcı Yerelleştirmesi)
  • navigator.browserLanguage (IE'ye Özgü - Tarayıcı Yerelleştirilmiş Dili)
  • navigator.systemLanguage (IE'ye Özgü - Windows İşletim Sistemi - Yerelleştirilmiş Dil)
  • navigator.userLanguage

Bunları bir javascript işlevine dönüştürün ve çoğu durumda doğru dili tahmin edebilmeniz gerekir. Zarif bir şekilde indirdiğinizden emin olun, bu nedenle dil seçim bağlantılarınızı içeren bir div bulundurun, böylece javascript yoksa veya yöntem işe yaramazsa kullanıcı yine de karar verebilir. Eğer işe yararsa, div'i gizlemeniz yeterlidir.

İstemci tarafında bunu yapmanın tek sorunu, ya tüm hizmet dilleri sunmanız veya doğru sürümü istemeden önce komut dosyasının çalışmasını ve dili algılamasını beklemenizdir. Belki de en popüler dil sürümünü varsayılan olarak sunmak, en az insanı rahatsız eder.

Düzenleme: İvan'ın ikinci çerez önerisi olurdu, ancak kullanıcının dili daha sonra her zaman değiştirebileceğinden emin olun; herkes tarayıcısının varsayılan dilini tercih etmez.


Önerileriniz için teşekkürler Phil. Makaleyle ilgili olarak, 6 yaşında ... güvenebileceğimizden emin değil misiniz?
Theo.T

1
Modern tarayıcıların navigator.language'i desteklediğinden şüpheleniyorum. Tarayıcım (Ubuntu 8.10'da FF3) 'tr-GB' bildiriyor. Birisi hala IE6 kullanıyorsa - insanların yaklaşık% 20'si - buna izin vermeye değer. IE6 8 yıl önce ortaya çıktı.
Phil H

IE 8 navigator.language'i desteklemez. Belki IE 9 olacak?
Spig

36

Tarayıcıların kullanıcının dilini saklamak için kullandığı birden çok yöntemi birleştirerek şu işlevi görürsünüz:

const getNavigatorLanguage = () => {
  if (navigator.languages && navigator.languages.length) {
    return navigator.languages[0];
  } else {
    return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
  }
}

İlk önce navigator.languagesdiziyi ilk öğesi için kontrol ederiz .
Sonra ya navigator.userLanguageya alırız navigator.language.
Bu başarısız olursa elde ederiz navigator.browserLanguage.
Sonunda, 'en'eğer her şey başarısız olursa onu ayarladık .


Ve işte seksi tek astar:

const getNavigatorLanguage = () => (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';

görünüşe göre navigator.userLanguage(IE için) gibi bir şey var . Tamamlamak için bunu ekleyebilirsiniz :)
pors

Neden basit değil navigator.languages[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'?
Emerica

@Curse Çünkü navigator.languagesolabilirundefined
Zenoo

@Zenoo Hangi tarayıcılarda olduğunu biliyor musunuz?
Emerica

(navigator.languages || [])[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'
Steve Bennett

10

Kullanıcının tercih ettiği diller ile sistem / tarayıcı yerel ayarı arasında bir fark vardır.

Bir kullanıcı tarayıcıda tercih edilen dilleri yapılandırabilir ve bunlar navigator.language(s) bir dil öncelikleri listesine göre içerik istemek için bir sunucudan kaynak isterken kullanılır ve kullanılır.

Bununla birlikte, tarayıcı yerel ayarı numara, tarih, saat ve para biriminin nasıl oluşturulacağına karar verecektir. Bu ayar muhtemelen en yüksek sıralama dilidir, ancak garanti yoktur. Mac ve Linux'ta, yerel ayar, kullanıcı dili tercihlerine bakılmaksızın sistem tarafından belirlenir. Windows'da, Chrome'da tercih edilen listedeki diller arasından seçilebilir.

Intl ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl ) kullanarak , geliştiriciler bu şeyleri oluşturmak için yerel ayarı geçersiz kılabilir / ayarlayabilir, ancak <input type="date">biçim gibi geçersiz kılınamaz .

Bu dili düzgün bir şekilde çıkarmak için bulduğum tek yol:

(new Intl.NumberFormat()).resolvedOptions().locale

( Intl.NumberFormat().resolvedOptions().localeayrıca işe yarıyor gibi görünüyor)

Bu, varsayılan yerel ayar için yeni bir NumberFormat örneği oluşturur ve sonra bu çözümlenmiş seçeneklerin yerel ayarını yeniden okur.


5

Bununla ilgili biraz araştırma yaptım ve şu ana kadar bulgularımı aşağıdaki tabloda özetledim

resim açıklamasını buraya girin

Bu nedenle önerilen çözüm, Accept-Languagebaşlığı çözümlemek ve web sitesinin dilini ayarlamak için istemciye iletmek için bir sunucu tarafı komut dosyası yazmaktır . Sunucunun istemcinin dil tercihini algılaması için neden ihtiyaç duyulması gariptir, ancak şu andaki dil böyle tespit etmek için başka çeşitli kesmek var, ancak Accept-Languagebaşlığı okumak benim anlayışım doğrultusunda önerilen çözümdür.


2

Ayrıca, ilk çağrı portunuz olması durumunda belgeden dili almaya çalışabilirsiniz, daha sonra insanlar JS dillerinin belge diliyle eşleşmesini isteyeceği için diğer araçlara geri dönebilirsiniz.

HTML5:

document.querySelector('html').getAttribute('lang')

eski:

document.querySelector('meta[http-equiv=content-language]').getAttribute('content')

Hiçbir gerçek kaynak zorunlu olarak% 100 güvenilir değildir, çünkü insanlar basitçe yanlış dilde yazabilirler.

Dili içeriğe göre belirlemenize izin verebilecek dil algılama kitaplıkları vardır.


2

Tüm cevapları kullandım ve tek satırlık bir çözüm oluşturdum:

const getLanguage = () => navigator.userLanguage || (navigator.languages && navigator.languages.length && navigator.languages[0]) || navigator.language || navigator.browserLanguage || navigator.systemLanguage || 'en';

console.log(getLanguage());

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.