2010-09-07 19 views

Trả lời

17

Bạn có thể quản lý $ language_suffix theo cài đặt này khi bạn không thể thêm mô-đun AcceptLanguageModule vào hệ thống của mình.

rewrite (.*) $1/$http_accept_language 

Một cách tiếp cận linh hoạt hơn sẽ sử dụng bản đồ:

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

... 

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

Thực ra không nên có khoảng trống giữa biểu thức ~ và biểu thức. –

+0

Điều này có yêu cầu AcceptLanguageModule không? –

+3

Không làm việc cho tôi, nó luôn đưa tôi đến trang tiếng Anh ngay cả khi tôi định cấu hình trình duyệt của mình cho tiếng Pháp chỉ –

-2

Vì vậy, đây là ví dụ biên soạn cho câu hỏi ban đầu (dựa trên trường hợp của tôi được xác nhận để làm việc với 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, tôi đã gặp sự cố tương tự và "lạm dụng" Lua để thực hiện chuyển hướng có thể dựa trên ngôn ngữ trình duyệt.

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

Lưu ý: NGINx cần phải có liblua biên dịch. Dành cho Debian/Ubuntu:

apt-get install nginx-extras 
7

Tôi nghĩ rằng nó không phải là ý tưởng tốt để sử dụng nginx map $http_accept_language vì đó không tuân thủ giá trị chất lượng (q trong Accept-Language tiêu đề). Hãy tưởng tượng bạn có:

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

Và khách hàng sẽ gửi Accept-Language: da, en-gb;q=0.8, en;q=0.7

Sử dụng bản đồ nginx sẽ luôn bản đồ $lang-en vì nó chỉ đơn giản là tìm thấy trong chuỗi tiêu đề. Nhưng bản đồ chính xác sẽ $lang = da (vì Danisch có giá trị chất lượng q=1 đó là lớn hơn sau đó tiếng Anh q=0.7 trong trường hợp này) Thông tin thêm về này trong RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

8

Nhược điểm của việc sử dụng AcceptLanguageModule là bạn không thể dựa vào cập nhật hệ thống tự động nữa . Và với mọi cập nhật nginx (thậm chí là an ninh), bạn phải tự biên dịch Nginx. Nhược điểm thứ hai là mô-đun giả định rằng ngôn ngữ chấp nhận được sắp xếp theo các giá trị chất lượng đã có. Tôi khá thích Lua vì nó có thể được cài đặt một cách dễ dàng trong distro debian dựa trên:

apt-get install nginx-extras 

Đồng nghiệp của tôi Fillipo làm lớn nginx-http-accept-lang kịch bản trong Lua. Nó xử lý một cách chính xác các giá trị chất lượng và chuyển hướng người dùng cho phù hợp. Tôi đã thực hiện small modification cho tập lệnh đó. Nó chấp nhận các ngôn ngữ được hỗ trợ như tham số đầu vào và trả về ngôn ngữ có trình độ nhất theo tiêu đề Accept-Language. Với giá trị trả lại bạn có thể làm bất cứ điều gì bạn muốn. Nó có thể được sử dụng để viết lại, thiết lập cookie lang ...

Tôi chỉ sử dụng xác định ngôn ngữ cho đường dẫn gốc (vị trí = /). Và cookie lang người dùng có tùy chọn trên trình duyệt. nginx conf của tôi trông như thế này:

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

điều này là khá tốt đẹp, nhưng tại sao không thực hiện một PR cho kịch bản gốc? – colthreepv

+0

Lấy cảm hứng từ giải pháp này, tôi đã đưa ra giải pháp hỗ trợ lấy thông số và cookie. Bạn có thể dùng thử tại đây: https://github.com/mallocator/nginx-lua-lang – Mallox

1

giải pháp đơn giản, mà không MapModule và AcceptLanguageModule:

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

Lưu ý rằng "đặt $ args hl = $ lang & $ args" đặt mã ngôn ngữ mong muốn (ví dụ: "vi", "fr", "es", v.v.) trong tham số truy vấn "hl". Tất nhiên bạn có thể sử dụng $ lang trong các quy tắc viết lại khác nếu thông số truy vấn không phù hợp. Ví dụ:

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

Ví dụ trên vẫn tốt, nhưng sẽ thất bại với lỗi 500 nếu trình duyệt không gửi bất kỳ tiêu đề Accept-Language nào.

Thêm này trên đầu trang của nó:

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

Cảm ơn bạn đã chia sẻ thông tin giá trị này. –

Các vấn đề liên quan