브라우저 내에서 사용자의 로캘을 결정하는 가장 좋은 방법


202

12 개 언어로 현지화 된 웹 사이트 (Flash)가 있으며 사용자의 브라우저 설정에 따라 기본값에 자동으로 정의하여 콘텐츠 액세스 단계를 최소화하고 싶습니다.

참고로 프록시 제한으로 인해 서버 스크립트를 사용할 수 없으므로 JavaScript 또는 ActionScript가 문제를 해결하는 데 적합하다고 생각합니다.

질문 :

  1. 사용자의 로캘을 '추측'하는 가장 좋은 방법은 무엇입니까?

  2. 도움이 될 수있는 기존의 간단한 클래스 / 기능이 있습니까 (복잡한 지역화 번들 없음)? 특히 모든 가능한 언어를 현명한 방법으로 더 적은 수 (내가 가진 번역)로 나눕니다.

  3. 그러한 솔루션을 어느 시점에서 신뢰할 수 있습니까?

  4. 다른 해결 방법이나 제안 사항이 있습니까?


브라우저가 사용자에 대한 메타 데이터를 공유 할 수있는 유일한 방법이며 요청은 URL과 헤더를 통하는 것입니다. 파이어 폭스를 잡고 요청이있을 때 전송되는 헤더를 살펴보십시오. 전형적인 요청 및 응답 헤더를 검사하는 것은 매우 흥미 롭습니다.
mP.

답변:


188

올바른 방법은 HTTP Accept-Language 를 보는 것입니다 서버로 전송 된 헤더를 보는 것입니다. 여기에는 사용자가 브라우저를 선호하도록 구성한 순서대로 가중치가 부여 된 언어 목록이 포함됩니다.

불행히도이 헤더는 JavaScript 내부에서 읽을 수 없습니다. 당신이 얻을 모든은 navigator.language웹 브라우저의 지역화 된 버전이 설치되어 있었는지를 알려줍니다. 이것은 반드시 사용자가 선호하는 언어와 같은 것은 아닙니다. IE에서는 대신 systemLanguage(OS 설치 언어) browserLanguage(와 동일 language) 및 userLanguage(사용자 구성 OS 영역)이 표시되며 모두 비슷하지 않습니다.

그 속성들 중에서 선택해야한다면, 나는 userLanguage처음으로 스니핑하고 language그 이후로 (그리고 그 언어가 사용 가능한 언어와 일치하지 않으면)보고 browserLanguage마지막으로 넘어갑니다 systemLanguage.

Accept-Language 헤더를 읽고 문자열에 헤더 값이있는 JavaScript 파일로 다시 뱉어내는 서버 측 스크립트를 인터넷의 다른 곳에 배치 할 수있는 경우 :

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

그런 다음 HTML에서 해당 외부 서비스를 가리키는 <script src>를 포함하고 JavaScript를 사용하여 언어 헤더를 구문 분석 할 수 있습니다. Accept-Language 구문 분석은 거의 항상 서버 측에서 수행 되므로이 작업을 수행하는 기존 라이브러리 코드를 모릅니다.

결국 어떤 일을 하든지, 어떤 사람들에게는 항상 잘못 추측 할 수 있기 때문에 사용자 재정의가 필요합니다. 종종 언어 설정을 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 요청에서 Accept-Language HTTP 헤더는 추가를 제외하고 navigator.languages ​​특성에 대해 동일한 값을 사용합니다. q 값 (품질 값) 필드 (예 : en-US; q = 0.8). "
S Meaden

3
업데이트 : 모든 언어 기본 설정을 반환하는 모든 최신 브라우저에서 지원되는 실험적 기능 (2020)이 있습니다. navigator.languages //["en-US", "zh-CN", "ja-JP"]이 기능은 2020 년에 브라우저의 95 % 이상에서 작동합니다.
Cornelius Roemer

1
navigator.languagesMDNcaniuse.com 에 따르면 현재 모든 주요 브라우저에서 사용할 수 있습니다 . 가장 현대적이고 역 호환 가능한 접근 방식을 위해 작은 (~ 200 바이트) 네비게이터 언어 패키지를 사용해보십시오 .
mindplay.dk

84

Chrome 및 Firefox 32 이상에서 navigator.languages는 사용자 환경 설정 순서대로 로케일 배열을 포함하지만 navigator.language보다 정확하지만 이전 버전과 호환되도록 (Chrome / IE / Firefox / Safari 테스트) 사용하려면 이:

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

2
IE9 및 IE10에서는 작동하지 않습니다. 그들을 위해, 대신 navigator.browserLanguage를 검사해야합니다.
user393274

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

4
@ChStark 그렇지 return navigator.languages[0] || navigator.language;않습니까?
James_

23
또한 올바른 "한 줄짜리"는 다음과 같습니다 return (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.language;. 그렇지 않으면 navigator.languages정의되지 않거나 비어 있으면 예외 가 발생합니다 .
Max Truxa

더욱 컴팩트 버전const getLang = () => navigator.language || navigator.browserLanguage || ( navigator.languages || [ "en" ] ) [ 0 ]
주앙 미구엘 브란 당

41

이 기사 에서는 브라우저 탐색기 오브젝트 의 다음 특성을 제안 합니다.

  • navigator.language (넷스케이프-브라우저 현지화)
  • navigator.browserLanguage (IE 별-브라우저 현지화 된 언어)
  • navigator.systemLanguage (IE- 특정-Windows OS-현지화 된 언어)
  • navigator.userLanguage

이것을 자바 스크립트 함수로 롤링하면 대부분의 상황에서 올바른 언어를 추측 할 수 있어야합니다. 자바 스크립트가 없거나 메소드가 작동하지 않는 경우에도 사용자가 계속 결정할 수 있도록 언어 선택 링크가 포함 된 div가 있어야합니다. 작동하면 div를 숨기십시오.

클라이언트 측 에서이 작업을 수행하는 유일한 문제는 모두를 제공한다는 것입니다 언어를 하거나 스크립트가 실행되어 올바른 버전을 요청하기 전에 언어를 감지 할 때까지 기다려야한다는 것입니다. 아마도 가장 인기있는 언어 버전을 기본으로 제공하면 가장 적은 사람들을 자극 할 것입니다.

편집 : 나는 Ivan의 쿠키 제안을 두 번째로 생각하지만 사용자가 나중에 언제든지 언어를 변경할 수 있는지 확인하십시오. 모든 사람이 브라우저의 기본 언어를 선호하는 것은 아닙니다.


제안 해 주셔서 감사합니다. 기사에 관해서는, 그것은 6 세입니다 ... 우리가 그것에 의존 할 수 있는지 확실하지 않습니까?
Theo.T

1
최신 브라우저가 모두 navigator.language를 지원한다고 생각합니다. 내 브라우저 (Ubuntu 8.10의 FF3)에서 'en-GB'를보고합니다. 누군가가 여전히 약 6 %의 사람들이 IE6을 사용하고 있다면 허용 할만한 가치가 있습니다. IE6는 8 년 전에 나타났습니다.
Phil H

IE 8은 navigator.language를 지원하지 않습니다. 아마도 IE 9은?
spig

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(IE의 경우) 와 같은 것이 있습니다 . 당신은 그것을 완성하기 위해 그것을 추가 할 수 있습니다 :)
pors

왜 간단하지 navigator.languages[0] || navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en'않습니까?
Emerica

@Curse 때문에 navigator.languages할 수 있습니다undefined
Zenoo

@Zenoo 어떤 브라우저에서 알고 있습니까?
Emerica

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

10

사용자가 선호하는 언어와 시스템 / 브라우저 로캘간에 차이가 있습니다.

사용자는 브라우저에서 원하는 언어를 구성 할 수 있으며 navigator.language(s)언어 우선 순위 목록에 따라 콘텐츠를 요청하기 위해 서버에서 리소스를 요청할 때 사용됩니다.

그러나 브라우저 로캘은 숫자, 날짜, 시간 및 통화를 렌더링하는 방법을 결정합니다. 이 설정은 가장 높은 순위의 언어 일 수 있지만 보장 할 수는 없습니다. Mac 및 Linux에서 로캘은 사용자 언어 기본 설정에 관계없이 시스템에 의해 결정됩니다. Windows에서 Chrome의 선호 목록에있는 언어 중 하나를 선택할 수 있습니다.

개발자는 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또한 작동하는 것 같습니다)

그러면 기본 로캘에 대한 새 NumberFormat 인스턴스가 생성되고 해결 된 옵션의 로캘이 다시 읽 힙니다.


5

나는 이것에 대해 약간의 연구를했고 & 지금까지 나의 결과를 아래 표에 요약했다.

여기에 이미지 설명을 입력하십시오

따라서 권장 솔루션은 서버 측 스크립트를 작성하여 Accept-Language헤더 를 구문 분석 하고 웹 사이트의 언어를 설정하기 위해 클라이언트에 전달하는 것입니다. 서버가 클라이언트의 언어 기본 설정을 감지 해야하는 이유는 이상하지만 현재와 같습니다. 언어를 감지하는 데 사용할 수있는 다양한 해킹이 있지만 Accept-Language헤더를 읽는 것이 내 이해에 따라 권장되는 솔루션입니다.


2

또한 문서에서 언어를 가져 오려면 첫 번째 호출 포트가되어야합니다. 그런 다음 사람들은 JS 언어가 문서 언어와 일치하기를 원할 때 다른 수단으로 넘어갑니다.

HTML5 :

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());

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.