需结合 map 指令、GeoIP2 模块(如 ngx_http_geoip2_module)与 return/rewrite 实现基于地理位置的动态跳转;先加载 GeoLite2 数据库并提取国家码,再用 map 映射国家码到目标 URL,最后通过 if + return 302 执行跳转,支持保留原始路径。

直接用 location 本身无法识别 IP 地理位置,它只匹配 URI 路径。要实现基于地理位置的动态跳转,必须结合 map 指令 + GeoIP 数据库(如 ngx_http_geoip2_module)+ rewrite 或 return 实现。
需要先启用 GeoIP 支持
Nginx 默认不内置 GeoIP 功能。需确认已安装并加载地理信息模块:
- 推荐使用
ngx_http_geoip2_module(支持 MaxMind GeoLite2 数据库,更准确、维护活跃) - 编译时添加
--add-dynamic-module=../ngx_http_geoip2_module,或通过包管理器安装对应模块 - 在
http块中加载数据库文件:geoip2 /etc/nginx/GeoLite2-Country.mmdb {<br> $geoip2_data_country_code country iso_code;<br> $geoip2_data_country_name country names en;<br> }
用 map 映射国家代码到目标 URL
map 指令用于将变量值(如国家码)映射为新变量,适合做条件跳转前的预处理:
- 定义映射关系,避免在每个
server或location中重复判断map $geoip2_data_country_code $redirect_url {<br> default "";<br> CN "https://cn.example.com";<br> US "https://us.example.com";<br> JP "https://jp.example.com";<br> KR "https://kr.example.com";<br> } - 该映射在请求解析早期执行,性能开销小,且支持嵌套逻辑(如按区域分组)
在 server 或 location 中触发跳转
有了映射变量后,用 if + return 或 rewrite 执行跳转:
- 推荐用
return 302 $redirect_url;,简洁安全,避免正则回溯风险 - 放在
server块顶层,确保所有路径都生效;若仅对特定路径生效,可放在对应location内 - 示例:
server {<br> listen 80;<br> server_name example.com;<br> if ($redirect_url) {<br> return 302 $redirect_url;<br> }<br> # 其他配置...<br> } - 注意:
if在location中可用,但不能嵌套,且不建议在location外大量使用复杂逻辑
跳转时保留原始路径(可选)
若需带参跳转(如 https://cn.example.com/path?utm=geo),可拼接变量:
- 改用
map构造完整跳转地址:map $geoip2_data_country_code $full_redirect {<br> default "";<br> CN "https://cn.example.com$request_uri";<br> US "https://us.example.com$request_uri";<br> } - 再配合
return 302 $full_redirect;即可保留原始 URI 和查询参数 - 注意:确保
$request_uri已 URL 编码,Nginx 默认保持原样传递,一般无需额外处理


















