2010-09-07 5 views

risposta

17

È possibile gestire $ language_suffix con questa impostazione quando non è possibile aggiungere il modulo AcceptLanguageModule nel proprio sistema.

rewrite (.*) $1/$http_accept_language 

Un approccio più resistente avrebbe usato una mappa:

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

... 

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

In realtà non ci dovrebbe essere uno spazio tra il ~ e l'espressione. –

+0

Richiede questo AcceptLanguageModule? –

+3

Non funziona per me, mi porta sempre alla pagina inglese anche se configuro il mio browser solo per il francese –

-2

Quindi, ecco l'esempio compilato per la domanda iniziale (basato sul mio caso verificato di lavorare 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

Ok, ho avuto lo stesso problema e "uso improprio" di Lua per rendere possibile un reindirizzamento basato sulla lingua del browser.

# 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 deve essere compilato da liblua. Per Debian/Ubuntu:

apt-get install nginx-extras 
7

penso che non è buona idea usare nginx map $http_accept_language perché che non onora valore di qualità (q in Accept-Language intestazione). Immaginiamo di avere:

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

E client invierà Accept-Language: da, en-gb;q=0.8, en;q=0.7

usando la mappa nginx sarà sempre mappare $lang-en perché semplicemente trovare nella stringa di intestazione. ma una corretta mappatura sarà $lang = da (perché Danisch ha valore di qualità q=1 che è più grande poi inglese q=0.7 in questo caso) Maggiori informazioni su questo nella RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

8

Lo svantaggio di usare AcceptLanguageModule è che non si può fare affidamento su aggiornamenti automatici del sistema più . E con ogni aggiornamento di nginx (anche di sicurezza), devi compilare Nginx da solo. Il secondo lato negativo è che il modulo presuppone che la lingua di accettazione sia già ordinata per valori di qualità. Io invece preferisco Lua perché può essere installato facilmente in distro debian based:

apt-get install nginx-extras 

mio collega Filippo reso grande nginx-http-accept-lang di script in Lua. Gestisce correttamente i valori di qualità e reindirizza l'utente di conseguenza. Ho fatto small modification a quello script. Accetta le lingue supportate come parametro di input e restituisce la lingua più qualificata in base all'intestazione Accept-Language. Con il valore restituito puoi fare quello che vuoi. Può essere usato per riscritture, impostazione di lang cookie ...

Sto solo usando la determinazione della lingua solo per il percorso root (posizione = /). E il cookie user lang ha la preferenza sul browser. mio nginx conf si presenta così:

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

questo è abbastanza bello, ma perché non fare un PR per la sceneggiatura originale? – colthreepv

+0

Ispirato da questa soluzione, ho trovato il mio che supporta parametri e cookie. Puoi provarlo qui: https://github.com/mallocator/nginx-lua-lang – Mallox

1

soluzione semplice, senza mapModule e AcceptLanguageModule:

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

Si noti che il "set $ args hl = $ lang & $ args" imposta il codice della lingua desiderata (ad esempio "en", "fr", "es", ecc.) nel parametro di query "hl". Ovviamente è possibile utilizzare $ lang in altre regole di riscrittura se il parametro della query non si adatta. Esempio:

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

Lua esempio di cui sopra va bene, ma verrà effettuata con errore 500 se il browser non invia le intestazioni Accept-Language.

Aggiungere questo su di esso:

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

Grazie per aver condiviso queste preziose informazioni. –