2010-09-07 94 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

相关问题