ब्राउज़र के भीतर उपयोगकर्ता के स्थान को निर्धारित करने का सबसे अच्छा तरीका


202

मेरे पास एक वेबसाइट है (फ्लैश) एक दर्जन भाषाओं में स्थानीयकृत है और मैं सामग्री को एक्सेस करने के चरणों को कम करने के लिए उपयोगकर्ता की ब्राउज़र सेटिंग्स के आधार पर एक डिफ़ॉल्ट मान को ऑटो-डिफाइन करना चाहता हूं।

FYI करें, मैं प्रॉक्सी प्रतिबंधों के कारण सर्वर-स्क्रिप्ट का उपयोग नहीं कर सकता, इसलिए मुझे लगता है कि समस्या को हल करने के लिए जावास्क्रिप्ट या एक्शनस्क्रिप्ट उपयुक्त होगा।

प्रशन:

  1. उपयोगकर्ता के स्थान को 'अनुमान' लगाने के लिए सबसे अच्छी विधि क्या होगी?

  2. क्या कोई मौजूदा साधारण कक्षाएं / फ़ंक्शन हैं जो मुझे बाहर निकालने में मदद कर सकते हैं (कोई जटिल स्थानीयकरण बंडल नहीं)? विशेष रूप से सभी संभव भाषाओं को स्मार्ट तरीके से छोटी संख्या (मेरे पास अनुवाद) में तोड़ने के लिए।

  3. मैं किस बिंदु पर इस तरह के समाधान पर भरोसा कर सकता हूं?

  4. कोई अन्य समाधान या सुझाव?


केवल एक ब्राउज़र अपने उपयोगकर्ता के बारे में मेटा डेटा साझा कर सकता है और अनुरोध URL और हेडर के माध्यम से है। फ़ायरफ़ॉक्स को पकड़ो और अनुरोध किए जाने पर भेजे जाने वाले हेडर पर एक नज़र डालें। ठेठ अनुरोध और प्रतिक्रिया हेडर की जांच करने के लिए इसका काफी दिलचस्प है।
एम.पी.

जवाबों:


188

उचित तरीका यह है कि सर्वर पर भेजे गए HTTP Accept-Language हेडर को देखें। इसमें उन भाषाओं की क्रमबद्ध, भारित सूची होती है, जिन्हें उपयोगकर्ता ने पसंद करने के लिए अपने ब्राउज़र को कॉन्फ़िगर किया है।

दुर्भाग्य से यह हेडर जावास्क्रिप्ट के अंदर पढ़ने के लिए उपलब्ध नहीं है; आपको केवल वह मिलता है navigator.language, जो आपको बताता है कि वेब ब्राउज़र का स्थानीयकृत संस्करण क्या स्थापित किया गया था। यह आवश्यक रूप से उपयोगकर्ता की पसंदीदा भाषा (ओं) के समान नहीं है। IE पर आपको इसके बजाय systemLanguage(OS स्थापित भाषा), browserLanguage(समान language) और userLanguage(उपयोगकर्ता कॉन्फ़िगर किया गया OS क्षेत्र) मिलता है, जो सभी समान रूप से अप्रभावी हैं।

अगर मुझे उन संपत्तियों में से चुनना था, तो मैं userLanguageपहली बार सूँघता हूँ , वापस गिरता हूँ languageऔर उसके बाद (यदि वे किसी भी उपलब्ध भाषा से मेल नहीं खाते हैं) browserLanguageऔर अंत में देखते हैं systemLanguage

यदि आप नेट पर कहीं और एक सर्वर-साइड स्क्रिप्ट रख सकते हैं, जो केवल एक्सेप्ट-लैंग्वेज हैडर को पढ़ता है और इसे स्ट्रिंग में हेडर मान के साथ जावास्क्रिप्ट फाइल के रूप में वापस थूकता है, जैसे:

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

तब आप HTML में उस बाहरी सेवा को इंगित करते हुए एक <script src> शामिल कर सकते हैं, और भाषा हेडर को पार्स करने के लिए जावास्क्रिप्ट का उपयोग कर सकते हैं। मुझे यह करने के लिए किसी भी मौजूदा लाइब्रेरी कोड का पता नहीं है, हालांकि, चूंकि एक्सेप्ट-लैंग्वेज पार्सिंग लगभग हमेशा सर्वर साइड पर की जाती है।

आप जो कुछ भी कर रहे हैं, आपको निश्चित रूप से एक उपयोगकर्ता ओवरराइड की आवश्यकता है क्योंकि यह हमेशा कुछ लोगों के लिए गलत अनुमान लगाएगा। अक्सर भाषा सेटिंग को URL में रखना सबसे आसान होता है (जैसे। Http: //www.example.com/en/site vs http: //www.example.com/de/site), और उपयोगकर्ता को क्लिक करने दें दोनों के बीच संबंध। कभी-कभी आप दोनों भाषा संस्करणों के लिए एक ही URL चाहते हैं, जिस स्थिति में आपको सेटिंग कुकीज़ में संग्रहीत करनी होगी, लेकिन यह उपयोगकर्ता एजेंटों को कुकीज़ और खोज इंजन के लिए कोई समर्थन नहीं दे सकता है।


11
MDN developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/… "उपयोगकर्ता के ब्राउज़र से प्रत्येक HTTP रिक्वेस्ट में एक्सेप्ट-लैंग्वेज HTTP हेडर, नेवीगेटर के लिए समान मान का उपयोग करता है। अतिरिक्त संपत्ति को छोड़कर संपत्ति का उपयोग करता है। qvalues ​​(गुणवत्ता मान) फ़ील्ड (जैसे en-US; q = 0.8)। "
एस मादेन

3
अद्यतन: अब (2020) सभी आधुनिक ब्राउज़रों द्वारा समर्थित एक प्रयोगात्मक सुविधा है जो भाषा वरीयता की एक सरणी लौटाती है: navigator.languages //["en-US", "zh-CN", "ja-JP"]इसे 2020 में कम से कम 95% ब्राउज़रों पर काम करना चाहिए।
कॉर्नेलियस रोमर

1
navigator.languagesMDN और caniuse.com दोनों के अनुसार , अब सभी प्रमुख ब्राउज़रों में उपलब्ध है - सबसे आधुनिक और पीछे-संगत दृष्टिकोण के लिए छोटे (~ 200 बाइट्स) नेविगेटर-भाषा पैकेज का प्रयास करें ।
mindplay.dk 10:18

84

Chrome और फ़ायरफ़ॉक्स 32+ पर, navigator.languages ​​में उपयोगकर्ता वरीयता के क्रम में स्थानों की एक सरणी होती है, और यह navigator.language की तुलना में अधिक सटीक है, हालांकि इसे पीछे की ओर संगत (परीक्षणित क्रोम / IE / फ़ायरफ़ॉक्स / सफारी) बनाने के लिए, फिर उपयोग करें यह:

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

2
यह IE9 और IE10 के लिए काम नहीं करता है। उनके लिए, आपको इसके बजाय navigator.browserLanguage की जांच करनी होगी।
user393274

2
वनलाइनर:function getLang(){ return ( navigator.language || navigator.languages[0] ); }
जोर्जगर्ज़ा

4
@ स्टार्क क्या ऐसा नहीं होना चाहिए return navigator.languages[0] || navigator.language;?
जेम्स_जुन

23
इसके अलावा, सही "वन-लाइनर" इस ​​तरह दिखाई देगा return (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.language;:। अन्यथा आप एक अपवाद प्राप्त करते हैं यदि navigator.languagesअपरिभाषित या खाली है।
मैक्स Truxa

एक और भी अधिक कॉम्पैक्ट संस्करण के लिएconst getLang = () => navigator.language || navigator.browserLanguage || ( navigator.languages || [ "en" ] ) [ 0 ]
जोओ मिगुएल ब्रैंडो

41

यह आलेख ब्राउज़र के नेविगेटर ऑब्जेक्ट के निम्नलिखित गुणों का सुझाव देता है :

  • navigator.language (नेटस्केप - ब्राउज़र स्थानीयकरण)
  • navigator.browserLanguage (IE- विशिष्ट - ब्राउज़र स्थानीय भाषा)
  • navigator.systemLanguage (आईई-विशिष्ट - विंडोज ओएस - स्थानीयकृत भाषा)
  • navigator.userLanguage

इन्हें एक जावास्क्रिप्ट फ़ंक्शन में रोल करें और आपको अधिकांश परिस्थितियों में, सही भाषा का अनुमान लगाने में सक्षम होना चाहिए। शालीनता से नीचा दिखाना सुनिश्चित करें, ताकि आपके भाषा विकल्प लिंक वाले एक डिव हो, ताकि अगर कोई जावास्क्रिप्ट या विधि काम न करे, तो उपयोगकर्ता अभी भी तय कर सकता है। अगर यह काम करता है, तो बस div को छिपाएं।

क्लाइंट की ओर से ऐसा करने में एकमात्र समस्या यह है कि या तो आप क्लाइंट के लिए सभी भाषाओं की सेवा करते हैं, या आपको तब तक इंतजार करना होगा जब तक स्क्रिप्ट चला नहीं है और सही संस्करण का अनुरोध करने से पहले भाषा का पता लगाया है। शायद एक डिफ़ॉल्ट के रूप में सबसे लोकप्रिय भाषा संस्करण की सेवा करना सबसे कम लोगों को परेशान करेगा।

संपादित करें: मैं इवान के कुकी का सुझाव दूंगा, लेकिन सुनिश्चित करें कि उपयोगकर्ता हमेशा बाद में भाषा बदल सकता है; हर कोई उस भाषा को पसंद नहीं करता है, जो उसके ब्राउज़र डिफॉल्ट करता है।


आपके सुझाव के लिए धन्यवाद फिल। लेख के बारे में, यह 6 साल पुराना है ... यकीन नहीं है कि हम इस पर भरोसा कर सकते हैं?
थियो

1
मुझे संदेह है कि आधुनिक ब्राउज़र सभी नेविगेटर का समर्थन करते हैं। भाषा। मेरा ब्राउज़र (Ubuntu 8.10 पर FF3) 'एन-जीबी' रिपोर्ट करता है। यदि कोई अभी भी IE6 का उपयोग कर रहा है - लगभग 20% लोग - तो यह उसके लिए अनुमति देने के लायक है। IE6 8 साल पहले दिखाई दिया।
फिल एच।

IE 8 नेविगेटर का समर्थन नहीं करता है। भाषा। शायद IE 9 होगा?
११'११ को

36

उपयोगकर्ता की भाषा को संग्रहीत करने के लिए कई तरीके ब्राउज़रों का उपयोग करके, आपको यह फ़ंक्शन मिलता है:

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

हम पहले navigator.languagesइसके पहले तत्व के लिए सरणी की जांच करते हैं ।
फिर हम navigator.userLanguageया तो मिल जाते हैं या navigator.language
यदि यह विफल हो जाता है तो हम प्राप्त करते हैं navigator.browserLanguage
अंत में, हम इसे सेट करते हैं 'en'यदि सब कुछ विफल हो गया।


और यहाँ सेक्सी एक लाइनर है:

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

वहाँ भी स्पष्ट रूप से navigator.userLanguage(आईई के लिए) के रूप में कुछ है । आप इसे पूरा करने के लिए इसे जोड़ सकते हैं :)
पोर्स

बस क्यों नहीं navigator.languages[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'?
एमरिका

@ कुरसी इसलिए navigator.languagesहो सकती हैundefined
ज़ेनू

@Zenoo क्या आप जानते हैं कि किन ब्राउज़रों पर?
एमेरिका

(navigator.languages || [])[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'
स्टीव बेनेट

10

उपयोगकर्ता की पसंदीदा भाषाओं और सिस्टम / ब्राउज़र लोकेल में अंतर होता है।

एक उपयोगकर्ता ब्राउज़र में पसंदीदा भाषाओं को कॉन्फ़िगर कर सकता है, और इन्हें navigator.language(s)भाषा प्राथमिकताओं की सूची के अनुसार सामग्री का अनुरोध करने के लिए, सर्वर से संसाधनों का अनुरोध करते समय उपयोग किया जाएगा , और इसका उपयोग किया जाएगा ।

हालांकि, ब्राउज़र लोकेल तय करेगा कि नंबर, तारीख, समय और मुद्रा कैसे रेंडर की जाए। यह सेटिंग संभवतः उच्चतम रैंकिंग भाषा है, लेकिन इसकी कोई गारंटी नहीं है। मैक और लिनक्स पर, स्थानीय भाषा उपयोगकर्ता की प्राथमिकताओं की परवाह किए बिना सिस्टम द्वारा तय किया जाता है। क्रोम पर पसंदीदा सूची में विंडोज़ पर भाषाओं के बीच चुना जा सकता है।

Intl ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl ) का उपयोग करके , डेवलपर्स इन चीजों को प्रस्तुत करने के लिए उपयोग करने के लिए लोकेल को ओवरराइड / सेट कर सकते हैं, लेकिन ऐसे तत्व हैं ओवरराइड नहीं किया जा सकता है, जैसे <input type="date">प्रारूप।

इस भाषा को ठीक से निकालने के लिए, मैंने जो एकमात्र तरीका पाया है वह है:

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

( Intl.NumberFormat().resolvedOptions().localeकाम भी लगता है)

यह डिफ़ॉल्ट लोकेल के लिए एक नया नंबरफ़ॉर्मट उदाहरण बनाएगा और फिर उन हल किए गए विकल्पों के स्थान को वापस पढ़ेगा।


5

मैंने इस बारे में थोड़ा शोध किया और मैंने अपने निष्कर्षों को अब तक नीचे दी गई तालिका में संक्षेप में प्रस्तुत किया है

यहां छवि विवरण दर्ज करें

इसलिए अनुशंसित समाधान है Accept-Languageहेडर को पार्स करने के लिए और वेबसाइट की भाषा सेट करने के लिए क्लाइंट को पास करने के लिए एक सर्वर साइड स्क्रिप्ट लिखना है । यह अजीब है कि क्लाइंट की भाषा वरीयता का पता लगाने के लिए सर्वर की आवश्यकता क्यों होगी, लेकिन यह है कि यह अब तक कैसे है भाषा का पता लगाने के लिए अन्य विभिन्न हैक उपलब्ध हैं लेकिन Accept-Languageहेडर को पढ़ना मेरी समझ के अनुसार अनुशंसित समाधान है।


2

आप दस्तावेज़ से भाषा प्राप्त करने का प्रयास भी कर सकते हैं, यह आपका पहला पोर्ट ऑफ़ कॉल होना चाहिए, फिर अन्य माध्यमों पर वापस आना क्योंकि अक्सर लोग अपनी जेएस भाषा को दस्तावेज़ की भाषा से मिलान करना चाहेंगे।

एचटीएमएल 5:

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

लिगेसी:

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

कोई वास्तविक स्रोत आवश्यक रूप से 100% विश्वसनीय नहीं है क्योंकि लोग बस गलत भाषा में डाल सकते हैं।

भाषा की पहचान करने वाले पुस्तकालय हैं जो आपको सामग्री द्वारा भाषा निर्धारित करने की अनुमति दे सकते हैं।


1

मैंने सभी उत्तरों का उपयोग किया और एक एकल पंक्ति समाधान बनाया:

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

console.log(getLanguage());

-1

आपने कहा कि आपकी वेबसाइट में फ्लैश है, फिर, एक अन्य विकल्प के रूप में, आप ऑपरेशन सिस्टम की भाषा प्राप्त कर सकते हैं flash.system.Capabilities.language- एक ऑपरेशन सिस्टम लोकेल का अनुमान लगाने के लिए ब्राउज़र के भीतर ओएस भाषा कैसे निर्धारित करें देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.