我正在尝试配置 nginx 以仅对首次访问者执行 geoIP 检查。
这个想法是,首次访问者应该被重定向到针对他们的语言/国家定制的页面版本。
我可以检查某个 cookie 是否存在。如果存在,则 nginx 可以继续,而不会重定向。
这种设置意味着所有首次访问者将被重定向到最适合其国家/语言的页面版本。同时,那些希望的用户仍然可以自由浏览之后可用的所有版本。
我相信 Google 也推荐对多语言/多站点网页采用这种设置。
问题是,如果将重写指令放在根位置之外,就会出现重定向循环。然而,由于美国版本与 /root 相同,因此位置内的重写配置起来更加困难。
如果未指定重写,则 geo_IP 值将通过 fastcgi 传递给 php,因此我认为除了重写本身之外,设置没有任何问题。
这是我的配置:
map $geoip2_data_country_code $country_url {
default example.com; ##This is the US version
GB example.com/uk;
CA example.com/ca;
}
server {
listen 443 ssl spdy default_server;
server_name example.com;
root /var/www/html;
if ($http_cookie !~ "cookie_to_check") {
rewrite ^ https://$country_url break;
#Appending $request_uri to the rewrite yields very similar results
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location /uk {
try_files $uri $uri/ /uk/index.php?$args;
}
location /ca {
try_files $uri $uri/ /ca/index.php?$args;
}
##Other locations
}
答案1
经过多次反复尝试后,该配置终于能够正常工作并按预期运行。
我之前的版本存在两个问题:
- Nginx 重写外部位置很混乱,它们会通过创建讨厌的循环而拒绝工作
Nginx 正在检查由 nginx 后面的 php 应用程序设置的 cookie 是否存在。感谢 @AlexeyTen 指出这一点。使用 nginx 有条件地设置额外的 cookie 就可以解决问题
map $geoip2_data_country_code $country_url { default example.com; ##This is the US version GB example.com/uk; CA example.com/ca; } server { listen 443 ssl spdy default_server; server_name example.com; root /var/www/html; location / { try_files $uri $uri/ /index.php?$args; if ($http_cookie !~ "country=set") { add_header Set-Cookie "country=set;Max-Age=31536000"; rewrite ^ $scheme://$country_url$request_uri break; } } location /uk { try_files $uri $uri/ /uk/index.php?$args; if ($http_cookie !~ "country=set") { add_header Set-Cookie "country=set;Max-Age=31536000"; rewrite ^ $scheme://$country_url$request_uri break; } } location /ca { try_files $uri $uri/ /ca/index.php?$args; if ($http_cookie !~ "country=set") { add_header Set-Cookie "country=set;Max-Age=31536000"; rewrite ^ $scheme://$country_url$request_uri break; } } ##Other locations }