2010-09-07 15 views

Respuesta

17

Puede administrar $ language_suffix con esta configuración cuando no puede agregar el módulo AcceptLanguageModule en su sistema.

rewrite (.*) $1/$http_accept_language 

Un enfoque más resistente usaría un mapa:

map $http_accept_language $lang { 
     default en; 
     ~es es; 
     ~fr fr; 
} 

... 

rewrite (.*) $1/$lang; 
+1

En realidad no debería haber un espacio entre el ~ y la expresión. –

+0

¿Esto requiere el AcceptLanguageModule? –

+3

No funciona para mí, siempre me lleva a la página en inglés, incluso si configuro mi navegador para francés solo –

-2

Así que aquí está el ejemplo compilado para la pregunta original (basado en mi caso verificado para trabajar con nginx-1.1.x):

map $http_accept_language $lang { 
    default en; 
    ~ru ru; 
    ~uk uk; 
} 

server { 
    server_name mysite.org; 
    # ... 
    rewrite (.*) http://mysite.org/$lang$1; 
} 
3

Bien, he tenido el mismo problema y "uso incorrecto" de Lua para hacer posible una redirección basada en el idioma del navegador.

# Use Lua for HTTP redirect so the site works 
# without the proxy backend. 
location =/{ 
    rewrite_by_lua ' 
     for lang in (ngx.var.http_accept_language .. ","):gmatch("([^,]*),") do 
      if string.sub(lang, 0, 2) == "en" then 
       ngx.redirect("/en/index.html") 
      end 
      if string.sub(lang, 0, 2) == "nl" then 
       ngx.redirect("/nl/index.html") 
      end 
      if string.sub(lang, 0, 2) == "de" then 
       ngx.redirect("/de/index.html") 
      end 
     end 
     ngx.redirect("/en/index.html") 
    '; 
} 

Nota: NGINx necesita tener compilado liblua. Para Debian/Ubuntu:

apt-get install nginx-extras 
7

creo que no es buena idea usar nginx map $http_accept_language porque que no respeta el valor de calidad (q en Accept-Language cabecera). Imaginemos que usted tiene:

map $http_accept_language $lang { 
    default en; 
    ~en en; 
    ~da da; 
} 

Y cliente enviará Accept-Language: da, en-gb;q=0.8, en;q=0.7

en el mapa nginx siempre mapa $lang-en porque simplemente encontrar en la cadena de encabezado. Pero asignación correcta será $lang = da (porque Danisch tiene valor de calidad q=1 que es más grande, entonces Inglés q=0.7 en este caso) Más sobre esto en el RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

8

La desventaja de usar AcceptLanguageModule es que no se puede confiar en las actualizaciones automáticas del sistema más . Y con cada actualización de nginx (incluso de seguridad), usted tiene que compilar Nginx usted mismo. El segundo inconveniente es que el módulo asume que el idioma de aceptación ya está ordenado por valores de calidad. Yo prefiero en lugar Lua, ya que puede ser fácilmente instalado en distribuciones basadas en Debian:

apt-get install nginx-extras 

Mi colega Fillipo hizo gran guión nginx-http-accept-lang en Lua. Maneja correctamente los valores de calidad y redirige al usuario en consecuencia. He hecho small modification en esa secuencia de comandos. Acepta los idiomas compatibles como parámetro de entrada y devuelve el idioma más calificado según el encabezado Aceptar idioma. Con el valor devuelto, puede hacer lo que quiera. Se puede usar para reescribir, configurar lang cookie ...

Solo estoy usando la determinación de idioma para la ruta de acceso raíz (location = /). Y la cookie de usuario lang tiene preferencia sobre el navegador. Mi conf nginx se ve así:

map $cookie_lang $pref_lang { 
    default ""; 
    ~en en; 
    ~sk sk; 
} 

server { 
    listen 80 default_server; 

    root /usr/share/nginx/html; 
    index index.html index.htm; 

    # Make site accessible from http://localhost/ 
    server_name localhost; 

    location =/{ 
     # $lang_sup holds comma separated languages supported by site 
     set $lang_sup "en,sk"; 
     set_by_lua_file $lang /etc/nginx/lang.lua $lang_sup; 
     if ($pref_lang) { 
      set $lang $pref_lang; 
     } 
     add_header Set-Cookie lang=$lang; 
     rewrite (.*) $scheme://$server_name/$lang$1; 
    } 

    location/{ 
     # First attempt to serve request as file, then 
     # as directory, then fall back to displaying a 404. 
     try_files $uri $uri/ =404; 
    } 
} 
+0

esto es bastante agradable, pero ¿por qué no hacer una PR en el script original? – colthreepv

+0

Inspirado por esta solución, creé el mío que admite parámetros y cookies. Puede probarlo aquí: https://github.com/mallocator/nginx-lua-lang – Mallox

1

solución simple, sin mapModule y AcceptLanguageModule:

if ($http_accept_language ~ ^(..)) { 
     set $lang $1; 
    } 
    set $args hl=$lang&$args; 

Tenga en cuenta que el "set $ args hl = $ lang & $ args" establece el código del idioma deseado (por ejemplo, "en", "fr", "es", etc.) en el parámetro de consulta "hl". Por supuesto, puede usar $ lang en otras reglas de reescritura si el parámetro de consulta no se ajusta. Ejemplo:

location ~/my/dir/path/ { 
      rewrite ^/my/dir/path/ /my/dir/path/$1/ break; 
      proxy_pass http://upstream_server; 
    } 
1

ejemplo Lua anterior está muy bien, pero con el error 500 si el navegador no envía ninguna cabecera Accept-Language.

Añadir esta en la parte superior de la misma:

if ngx.var.http_accept_language == nil then 
ngx.redirect("/en/") 
end 
+0

Gracias por compartir esta valiosa información. –

Cuestiones relacionadas