如何根据客户端浏览器的语言重写nginx中的位置?如何根据客户端浏览器的语言重写nginx中的位置?
例如: 我的浏览器接受语言是'uk,ru,en'。 当我请求位置mysite.org nginx必须转发到mysite.org/uk
如何根据客户端浏览器的语言重写nginx中的位置?如何根据客户端浏览器的语言重写nginx中的位置?
例如: 我的浏览器接受语言是'uk,ru,en'。 当我请求位置mysite.org nginx必须转发到mysite.org/uk
当您无法将AcceptLanguageModule模块添加到您的系统时,您可以通过此设置管理$ language_suffix。
rewrite (.*) $1/$http_accept_language
更有弹性的方法将使用地图:
map $http_accept_language $lang {
default en;
~es es;
~fr fr;
}
...
rewrite (.*) $1/$lang;
因此,这里的原始问题的编译例子(根据我的情况证实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;
}
好吧,我有同样的问题和“滥用”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
我认为这不是好主意,使用nginx的map $http_accept_language
因为 它不兑现质量值(q
在Accept-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
使用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;
}
}
这是相当不错的,但为什么不对原始脚本进行PR? – colthreepv 2015-09-17 15:16:01
受此解决方案的启发,我提出了自己的支持获取参数和cookie的方案。你可以在这里试试:https://github.com/mallocator/nginx-lua-lang – Mallox 2016-04-06 22:15:43
简单的解决方案,而无需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;
}
的Lua例子是好的,但将与误差500失败,如果浏览器不发送任何接受语言标头。
添加这在它的上面:
if ngx.var.http_accept_language == nil then
ngx.redirect("/en/")
end
感谢分享这些有价值的信息。 – 2017-05-13 18:43:12
您可以使用nginx_accept_language_module。 Nginx必须重新编译,但它的工作量要少于整合Lua。
实际上〜和表达之间不应该有空格。 – 2012-10-09 20:41:49
这是否需要AcceptLanguageModule? – 2013-09-24 14:36:42
不适合我,它总是把我带到英文页面,即使我只为法语配置我的浏览器 – 2013-10-13 13:59:58