2010-09-07 81 views

回答

17

當您無法將AcceptLanguageModule模塊添加到您的系統時,您可以通過此設置管理$ language_suffix。

rewrite (.*) $1/$http_accept_language 

更有彈性的方法將使用地圖:

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

... 

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

實際上〜和表達之間不應該有空格。 – 2012-10-09 20:41:49

+0

這是否需要AcceptLanguageModule? – 2013-09-24 14:36:42

+3

不適合我,它總是把我帶到英文頁面,即使我只爲法語配置我的瀏覽器 – 2013-10-13 13:59:58

-2

因此,這裏的原始問題的編譯例子(根據我的情況證實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

好吧,我有同樣的問題和「濫用」Lua根據瀏覽器語言做出可能的重定向。

# 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") 
    '; 
} 

注:NGINx需要編譯liblua。對於Debian/Ubuntu的:

apt-get install nginx-extras 
7

我認爲這不是好主意,使用nginx的map $http_accept_language因爲 它不兌現質量值(qAccept-Language頭)。 讓我們想象一下,你有:

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

和客戶端將發送Accept-Language: da, en-gb;q=0.8, en;q=0.7

使用nginx的地圖將始終映射到$lang因爲en它只是在頭部字符串找到。 但正確的映射將$lang = da(因爲Danisch具有質量值q=1這是更大然後英語q=0.7在這種情況下) 更多關於這在RFC:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

8

使用AcceptLanguageModule的缺點是,你不能依靠系統自動更新了。每次更新nginx(甚至是安全的),你都必須自己編譯Nginx。 第二個缺點是該模塊假定accept-language已經按質量值排序。 我寧可選擇Lua中,因爲它可以很容易地在基於Debian的發行版被安裝:

apt-get install nginx-extras 

我的同事菲利波Lua中取得了很大的nginx-http-accept-lang腳本。它正確處理質量值並相應地重定向用戶。 我製作了small modification這個腳本。它接受支持的語言作爲輸入參數,並根據Accept-Language頭返回最合適的語言。隨着返回值,你可以做任何你想要的。它可以用於重寫,設置朗曲奇...

我只使用語言確定根路徑(位置= /)。用戶lang cookie對瀏覽器有偏好。 我的nginx的conf看起來是這樣的:

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

這是相當不錯的,但爲什麼不對原始腳本進行PR? – colthreepv 2015-09-17 15:16:01

+0

受此解決方案的啓發,我提出了自己的支持獲取參數和cookie的方案。你可以在這裏試試:https://github.com/mallocator/nginx-lua-lang – Mallox 2016-04-06 22:15:43

1

簡單的解決方案,而無需MapModule和AcceptLanguageModule:

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

注意 「設置的$ args HL = $ LANG &的$ args」 設置想要的語言代碼(例如「en」,「fr」,「es」等)在「hl」查詢參數中。 當然,如果查詢參數不適合,您可以在其他重寫規則中使用$ lang。 實施例:以上

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

的Lua例子是好的,但將與誤差500失敗,如果瀏覽器不發送任何接受語言標頭。

添加這在它的上面:

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

感謝分享這些有價值的信息。 – 2017-05-13 18:43:12

相關問題