pais - JavaScript para detectar la preferencia de idioma del navegador
detectar idioma por ip (26)
Acabo de llegar a esto. Combina la nueva sintaxis de desestructuración de JS con algunas operaciones estándar para recuperar el idioma y la configuración regional.
var [lang, locale] = (((navigator.userLanguage || navigator.language).replace(''-'', ''_'')).toLowerCase()).split(''_'');
Espero que ayude a alguien
Esta pregunta ya tiene una respuesta aquí:
He estado tratando de detectar la preferencia de idioma del navegador usando JavaScript.
Si configuro el idioma del navegador en IE en Tools>Internet Options>General>Languages
, ¿cómo leo este valor con JavaScript?
El mismo problema para Firefox. No puedo detectar la configuración de tools>options>content>languages
usando navigator.language
.
Usando navigator.userLanguage
, detecta la configuración realizada a través de Start>ControlPanel>RegionalandLanguageOptions>Regional Options
pestaña Start>ControlPanel>RegionalandLanguageOptions>Regional Options
.
He probado con navigator.browserLanguage
y navigator.systemLanguage
pero ninguno devuelve el valor para la primera configuración ( Tools>InternetOptions>General>Languages
)
Encontré un link que discute esto en detalle, pero la pregunta sigue sin respuesta :(
Actualización del año 2014.
Ahora hay una manera de obtener Accept-Languages en Firefox y Chrome usando navigator.languages (funciona en Chrome> = 32 y Firefox> = 32)
Además, navigator.language en Firefox en estos años refleja el lenguaje de contenido más preferido, no el idioma de la interfaz de usuario. Pero como esta noción aún no es compatible con otros navegadores, no es muy útil.
Por lo tanto, para obtener el idioma de contenido más preferido cuando sea posible, y usar el idioma de la interfaz de usuario como alternativa:
navigator.languages
? navigator.languages[0]
: (navigator.language || navigator.userLanguage)
Basado en la respuesta aquí Accediendo a los encabezados HTTP de la página web en JavaScript , construí el siguiente script para obtener el idioma del navegador:
var req = new XMLHttpRequest();
req.open(''GET'', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
var contentLanguage = headers.match( /^content-language/:(.*)$/gm );
if(contentLanguage[0]) {
return contentLanguage[0].split(":")[1].trim().toUpperCase();
}
Creo que el principal problema aquí es que la configuración del navegador en realidad no afecta la propiedad navigator.language
que se obtiene a través de javascript.
Lo que sí afectan es el encabezado HTTP ''Accept-Language'', pero parece que este valor no está disponible para javascript en absoluto. (Probablemente el motivo por el que @anddoutoi declara que no puede encontrar una referencia que no incluya al servidor).
He codificado una solución alternativa: he encontrado un script de motor de aplicación de google en http://ajaxhttpheaders.appspot.com que le devolverá los encabezados de solicitud HTTP a través de JSONP.
(Nota: este es un truco que solo se debe usar si no tiene un back-end disponible que pueda hacer esto por usted. En general, no debe hacer llamadas a archivos javascript alojados por terceros en sus páginas, a menos que tenga una muy alta nivel de confianza en el host.)
Tengo la intención de dejarlo allí a perpetuidad, así que siéntase libre de usarlo en su código.
Aquí hay un código de ejemplo (en jQuery) sobre cómo podría usarlo
$.ajax({
url: "http://ajaxhttpheaders.appspot.com",
dataType: ''jsonp'',
success: function(headers) {
language = headers[''Accept-Language''];
nowDoSomethingWithIt(language);
}
});
Espero que alguien encuentre esto útil.
Edición: he escrito un pequeño complemento de jQuery en github que envuelve esta funcionalidad: https://github.com/dansingerman/jQuery-Browser-Language
Edición 2: como se solicita aquí es el código que se ejecuta en AppEngine (realmente trivial):
class MainPage(webapp.RequestHandler):
def get(self):
headers = self.request.headers
callback = self.request.get(''callback'')
if callback:
self.response.headers[''Content-Type''] = ''application/javascript''
self.response.out.write(callback + "(")
self.response.out.write(headers)
self.response.out.write(")")
else:
self.response.headers[''Content-Type''] = ''text/plain''
self.response.out.write("I need a callback=")
application = webapp.WSGIApplication(
[(''/'', MainPage)],
debug=False)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
Edit3: Tenga abierto el código del motor de la aplicación aquí: https://github.com/dansingerman/app-engine-headers
DanSingerman tiene una muy buena solución para esta pregunta.
La única fuente confiable para el idioma está en el encabezado de solicitud HTTP. Por lo tanto, necesita una secuencia de comandos del lado del servidor para responderle el encabezado de solicitud o al menos el campo Accept-Language
.
Aquí hay un servidor Node.js muy simple que debería ser compatible con DanSingermans jQuery plugin.
var http = require(''http'');
http.createServer(function (req, res) {
res.writeHead(200, {''Content-Type'': ''text/plain''});
res.end(JSON.stringify(req.headers));
}).listen(80,''0.0.0.0'');
En primer lugar, discúlpeme por mi inglés. Me gustaría compartir mi código, porque funciona y es diferente a los demás. En este ejemplo, si habla francés (Francia, Bélgica u otro idioma francés) se le redirige a la página de francés, de lo contrario a la página de inglés, según la configuración del navegador:
<script type="text/javascript">
$(document).ready(function () {
var userLang = navigator.language || navigator.userLanguage;
if (userLang.startsWith("fr")) {
window.location.href = ''../fr/index.html'';
}
else {
window.location.href = ''../en/index.html'';
}
});
</script>
Encontré este fragmento de código para detectar el lenguaje del navegador en el módulo Angular Translate , que puede encontrar la fuente here . Modifiqué ligeramente el código reemplazando angular.isArray con Array.isArray para hacerlo independiente de la biblioteca Angular.
var getFirstBrowserLanguage = function () {
var nav = window.navigator,
browserLanguagePropertyKeys = [''language'', ''browserLanguage'', ''systemLanguage'', ''userLanguage''],
i,
language;
// support for HTML 5.1 "navigator.languages"
if (Array.isArray(nav.languages)) {
for (i = 0; i < nav.languages.length; i++) {
language = nav.languages[i];
if (language && language.length) {
return language;
}
}
}
// support for other well known properties in browsers
for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
language = nav[browserLanguagePropertyKeys[i]];
if (language && language.length) {
return language;
}
}
return null;
};
console.log(getFirstBrowserLanguage());
Forma Javascript
var language = window.navigator.userLanguage || window.navigator.language;//returns value like ''en-us''
Si está utilizando el complemento jQuery.i18n , puede usar:
jQuery.i18n.browserLang();//returns value like ''"en-US"''
He estado usando la respuesta de Hamid por un tiempo, pero en casos donde la matriz de idiomas es como ["en", "en-GB", "en-US", "fr-FR", "fr", "en -ZA "] devolverá" en ", cuando" en-GB "sería una mejor coincidencia.
Mi actualización (a continuación) devolverá el primer código de formato largo, por ejemplo, "en-GB", de lo contrario, devolverá el primer código corto, por ejemplo, "en", de lo contrario, devolverá el valor nulo.
function getFirstBrowserLanguage() {
var nav = window.navigator,
browserLanguagePropertyKeys = [''language'', ''browserLanguage'', ''systemLanguage'', ''userLanguage''],
i,
language,
len,
shortLanguage = null;
// support for HTML 5.1 "navigator.languages"
if (Array.isArray(nav.languages)) {
for (i = 0; i < nav.languages.length; i++) {
language = nav.languages[i];
len = language.length;
if (!shortLanguage && len) {
shortLanguage = language;
}
if (language && len>2) {
return language;
}
}
}
// support for other well known properties in browsers
for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
language = nav[browserLanguagePropertyKeys[i]];
len = language.length;
if (!shortLanguage && len) {
shortLanguage = language;
}
if (language && len > 2) {
return language;
}
}
return shortLanguage;
}
console.log(getFirstBrowserLanguage());
La respuesta de Dan Singerman tiene un problema que el encabezado obtenido debe usarse de inmediato, debido a la naturaleza asíncrona del ajax de jQuery. Sin embargo, con su servidor de aplicaciones de Google, escribí lo siguiente, de modo que el encabezado se establece como parte de la configuración inicial y se puede usar más adelante.
<html>
<head>
<script>
var bLocale=''raw''; // can be used at any other place
function processHeaders(headers){
bLocale=headers[''Accept-Language''];
comma=bLocale.indexOf('','');
if(comma>0) bLocale=bLocale.substring(0, comma);
}
</script>
<script src="jquery-1.11.0.js"></script>
<script type="application/javascript" src="http://ajaxhttpheaders.appspot.com?callback=processHeaders"></script>
</head>
<body>
<h1 id="bLocale">Should be the browser locale here</h1>
</body>
<script>
$("#bLocale").text(bLocale);
</script>
</html>
No hay una manera decente de obtener esa configuración, al menos no algo independiente del navegador.
Pero el servidor tiene esa información, porque forma parte del encabezado de solicitud HTTP (el campo Accept-Language, vea http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 )
Así que la única forma confiable es obtener una respuesta del servidor. Necesitará algo que se ejecute en el servidor (como .asp, .jsp, .php, CGI) y esa "cosa" puede devolver esa información. Buenos ejemplos aquí: http://www.developershome.com/wap/detection/detection.asp?page=readHeader
No puedo encontrar una sola referencia que indique que es posible sin involucrar al servidor.
MSDN en:
- navegador. browserLanguage
- navegador. systemLanguage
- navegador. userLanguage
Desde browserLanguage:
En Microsoft Internet Explorer 4.0 y versiones anteriores, la propiedad browserLanguage refleja el idioma de la interfaz de usuario del navegador instalado. Por ejemplo, si instala una versión japonesa de Windows Internet Explorer en un sistema operativo en inglés, browserLanguage sería ja.
Sin embargo, en Internet Explorer 5 y versiones posteriores, la propiedad browserLanguage refleja el idioma del sistema operativo independientemente de la versión de idioma instalada de Internet Explorer. Sin embargo, si está instalada la versión de Microsoft Windows 2000 MultiLanguage, la propiedad browserLanguage indica el idioma establecido en los menús y cuadros de diálogo actuales del sistema operativo, como se encuentra en las Opciones regionales del Panel de control. Por ejemplo, si instala una versión japonesa de Internet Explorer 5 en un sistema operativo en inglés (Reino Unido), browserLanguage sería en-gb. Si instala Windows 2000 MultiLanguage versión y configura el idioma de los menús y cuadros de diálogo en francés, browserLanguage sería fr, aunque tenga una versión japonesa de Internet Explorer.
Nota Esta propiedad no indica el idioma o los idiomas establecidos por el usuario en las Preferencias de idioma, ubicadas en el cuadro de diálogo Opciones de Internet.
Además, parece que browserLanguage
está en desuso porque IE8 no lo enumera
Para lo que vale, la biblioteca de Selector de Idioma Universal de Wikimedia tiene ganchos para hacer esto: https://www.mediawiki.org/wiki/Extension:UniversalLanguageSelector
Consulte la función getFrequentLanguageList en resources / js / ext.uls.init.js. Enlace directo: https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/extensions/UniversalLanguageSelector.git;a=blob;f=resources/js/ext.uls.init.js;hb=HEAD
Todavía depende del servidor, o más específicamente, de la API de MediaWiki. La razón por la que lo muestro es que puede proporcionar un buen ejemplo de cómo obtener toda la información útil sobre el idioma del usuario: idioma del navegador, Aceptar idioma, geolocalización (con información de país / idioma del CLDR) y, por supuesto, preferencias del sitio propio del usuario.
Para quien busca la solución Java Server.
Aquí está RestEasy
@GET
@Path("/preference-language")
@Consumes({"application/json", "application/xml"})
@Produces({"application/json", "application/xml"})
public Response getUserLanguagePreference(@Context HttpHeaders headers) {
return Response.status(200)
.entity(headers.getAcceptableLanguages().get(0))
.build();
}
Si está desarrollando una aplicación / extensión de Chrome, use la API chrome.i18n .
chrome.i18n.getAcceptLanguages(function(languages) {
console.log(languages);
// ["en-AU", "en", "en-US"]
});
Si está utilizando ASP .NET MVC y desea obtener el encabezado de idiomas aceptados desde JavaScript, aquí hay un ejemplo de solución que no implica ninguna solicitud asíncrona.
En su archivo .cshtml, almacene el encabezado de forma segura en el atributo de datos de un div:
<div data-languages="@Json.Encode(HttpContext.Current.Request.UserLanguages)"></div>
Luego, su código JavaScript puede acceder a la información, por ejemplo, utilizando JQuery:
<script type="text/javascript">
$(''[data-languages]'').each(function () {
var languages = $(this).data("languages");
for (var i = 0; i < languages.length; i++) {
var regex = /[-;]/;
console.log(languages[i].split(regex)[0]);
}
});
</script>
Por supuesto, puede utilizar un enfoque similar con otras tecnologías de servidor como han mencionado otros.
Si no desea confiar en un servidor externo y tiene uno propio, puede usar un script PHP simple para lograr el mismo comportamiento que la respuesta de @DanSingerman.
languageDetector.php :
<?php
$lang = substr($_SERVER[''HTTP_ACCEPT_LANGUAGE''], 0, 2);
echo json_encode($lang);
?>
Y solo cambia estas líneas desde el script jQuery:
url: "languageDetector.php",
dataType: ''json'',
success: function(language) {
nowDoSomethingWithIt(language);
}
Si solo necesita admitir ciertos navegadores modernos, ahora puede usar:
navigator.languages
que devuelve una matriz de las preferencias de idioma del usuario en el orden especificado por el usuario.
A partir de ahora (septiembre de 2014), esto funciona en: Chrome (v37), Firefox (v32) y Opera (v24)
Pero no en: IE (v11)
Si tiene el control de un backend y está usando django, una implementación de 4 líneas de la idea de Dan es:
def get_browser_lang(request):
if request.META.has_key(''HTTP_ACCEPT_LANGUAGE''):
return JsonResponse({''response'': request.META[''HTTP_ACCEPT_LANGUAGE'']})
else:
return JsonResponse({''response'': settings.DEFAULT_LANG})
entonces en urls.py:
url(r''^browserlang/$'', views.get_browser_lang, name=''get_browser_lang''),
y en la parte delantera:
$.get(lg(''SERVER'') + ''browserlang/'', function(data){
var lang_code = data.response.split('','')[0].split('';'')[0].split(''-'')[0];
});
(tienes que configurar DEFAULT_LANG en settings.py por supuesto)
Tengo un hack que creo que usa muy poco código y es bastante confiable.
Ponga los archivos de su sitio en un subdirectorio. SSL en su servidor y cree enlaces simbólicos a ese subdirectorio donde se almacenan sus archivos que indican sus idiomas.
Algo como esto:
ln -s /var/www/yourhtml /var/www/en
ln -s /var/www/yourhtml /var/www/sp
ln -s /var/www/yourhtml /var/www/it
Use su servidor web para leer HTTP_ACCEPT_LANGUAGE y redirigir a estos "subdirectorios diferentes" de acuerdo con el valor del idioma que proporciona.
Ahora puede usar window.location.href de Javascript para obtener su url y usarla en condicionales para identificar de manera confiable el idioma preferido.
url_string = window.location.href;
if (url_string = "http://yoursite.com/it/index.html") {
document.getElementById("page-wrapper").className = "italian";
}
Tuve el mismo problema, y escribí la siguiente biblioteca única de front-end que envuelve el código para múltiples navegadores. No es mucho código, pero es bueno no tener que copiar y pegar el mismo código en varios sitios web.
Consíguelo: acceptedlanguages.js
Úsalo:
<script src="acceptedlanguages.js"></script>
<script type="text/javascript">
console.log(''Accepted Languages: '' + acceptedlanguages.accepted);
</script>
Siempre devuelve una matriz, ordenada por preferencia de los usuarios. En Safari & IE, la matriz siempre es de una sola longitud. En FF y Chrome puede ser más de un idioma.
Tuve un enfoque diferente, esto podría ayudar a alguien en el futuro:
El cliente quería una página donde poder intercambiar idiomas. Necesitaba dar formato a los números con esa configuración (no la configuración del navegador / no con ninguna configuración predefinida)
así que establezco una configuración inicial dependiendo de la configuración (i18n)
$clang = $this->Session->read(''Config.language'');
echo "<script type=''text/javascript''>var clang = ''$clang''</script>";
Más adelante en el script, utilicé una función para determinar qué formación de número necesito
function getLangsettings(){
if(typeof clang === ''undefined'') clang = navigator.language;
//console.log(clang);
switch(clang){
case ''de'':
case ''de-de'':
return {precision : 2, thousand : ".", decimal : ","}
case ''en'':
case ''en-gb'':
default:
return {precision : 2, thousand : ",", decimal : "."}
}
}
así que utilicé el idioma establecido de la página y, como alternativa, utilicé la configuración del navegador.
lo que debería ser útil para propósitos de prueba también.
Dependiendo de sus clientes puede que no necesite esa configuración.
navigator.userLanguage
para IE
window.navigator.language
para firefox / opera / safari
var language = navigator.languages && navigator.languages[0] || // Chrome / Firefox
navigator.language || // All browsers
navigator.userLanguage; // IE <= 10
console.log(language);
- developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/…
- https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language
Pruebe la plantilla PWA https://github.com/StartPolymer/progressive-web-app-template
<script type="text/javascript">
var lang = window.navigator.languages ? window.navigator.languages[0] : null;
lang = lang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;
if (lang.indexOf(''-'') !== -1)
lang = lang.split(''-'')[0];
if (lang.indexOf(''_'') !== -1)
lang = lang.split(''_'')[0];
</script>
Solo necesitaba el componente principal para mis necesidades, pero puedes usar la cadena completa fácilmente. Funciona con las últimas versiones de Chrome, Firefox, Safari e IE10 +.
var language = window.navigator.userLanguage || window.navigator.language;
alert(language); //works IE/SAFARI/CHROME/FF
window.navigator.userLanguage
es solo para IE y es el idioma establecido en el Panel de control de Windows - Opciones regionales y NO en el idioma del navegador, pero puede suponer que un usuario que utiliza una máquina con la configuración regional de Windows establecida en Francia es probablemente un usuario francés.
navigator.language
es FireFox y todos los demás navegadores.
Algún código de idioma: ''it''
= italy, ''en-US''
= inglés US, etc.
Como lo indican rcoup y The WebMacheter en los comentarios a continuación, esta solución no le permitirá discriminar entre los dialectos en inglés cuando los usuarios están viendo el sitio web en navegadores que no sean IE.
window.navigator.language
(Chrome / FF / Safari) devuelve siempre el idioma del navegador y no el idioma preferido del navegador, pero: "es bastante común que los hablantes de inglés (gb, au, nz, etc.) tengan una versión de Firefox en-us / Chrome / Safari ". Por window.navigator.language
tanto, window.navigator.language
aún devolverá en-US
incluso si el idioma preferido del usuario es en-GB
.