# Nginx根据用户ip返回对应地区语言

1 Nginx 编译进 geoip2 模块后更改主配置 http 部分    （geoip2 比geoip 更优秀）

```nginx
    #Nginx 编译进geoip模块后在主配置http内添加
    #开启CDN后获取访客真实IP地址
    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Forwarded-For;
    ## GEOIP2 国家
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
          $geoip2_Country_code country iso_code;
    }
    ## GEOIP2 城市 
    geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
          $geoip2_City_code country iso_code;
    }
    # 好单独为 城市级别 单独设置
```

2 域名的nginx 配置内添加负载均衡配置

```nginx
upstream ben {
    ip_hash;
    server 1.1.1.1 weight=1 max_fails=2 fail_timeout=2s;
    server 2.2.2.2 weight=2 max_fails=2 fail_timeout=2s;
    server 3.3.3.3 weight=2 max_fails=2 fail_timeout=2s;
}
```

3 伪静态内写 ip 地区转化对应语言逻辑

```nginx
#larvel 框架前台代码加伪静态
location / {
#初始化语言变量
set $language 0;
if ($geoip2_country_code = CN) { #祖国
  set $language "1";
  add_header  accept-language zh-CN;
}
if ($geoip2_country_code = MO) { #澳门
  set $language "2";
  add_header  accept-language zh-TW;
}
if ($geoip2_country_code = HK) { #香港
  set $language "3";
  add_header  accept-language zh-TW;
}
if ($geoip2_country_code = TW) { #台湾
  set $language "4";
  add_header  accept-language zh-TW;
}
if ($geoip2_country_code = VN) { #越南
  set $language "5";
  add_header  accept-language vi-VN;
}
if ($geoip2_country_code = VN) { #神奇的国家
  set $language "5";
  add_header  accept-language zh-CN;
}
#访客ip非上述地区就默认返回英语语言标识
if ($language = 0){
    add_header  accept-language en;
}
        try_files $uri $uri/ /index.html; #larvel 框架前台代码特定伪静态
            #通过负载均衡转发到后台服务器
            proxy_pass http://ben;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #携带根据ip地区更改后的语言
            proxy_set_header Accept-Language $http_accept_language; 
            proxy_set_header token $http_token;
   }
```

4 然后前端就能感觉到用户语言 lang 了

```javascript
// vue项目的多语言/国际化插件vue-i18n
// 想实现的效果：需要在web中实现多语言的切换，当用户语言切换完成后下次重新打开网页，也是上次设置的语言进行显示

// 1、在用户点击切换语言后，把选择的语言版本保存在cookie或storage中


//写入cookie函数
function setCookie(name,value) {
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
}

//获取cookie
function getCookie(name) {
    var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
    if(arr=document.cookie.match(reg))
    return unescape(arr[2]);
    else
    return null;
}

//setCookie('lan','zh-TW');    繁体中文
//setCookie('lan','zh-CN');    简体中文
//setCookie('lan','en');       英文
//setCookie('lan','vi-VN');    越南语

// 2、在包含静态文本的标签中，添加一个属性：set-lan=”html:name” 
// 属性值中的 html 代表内容的位置，name 代表要替换的文字的标识 

<span set-lan="html:name">名字</span>
<input type="text" value="名字" set-lan="val:name" />

// 这些需要在开发过程中添加进去，并且，要切换语言文字的外面都必须要有一个标签包裹，否则无法进行切换；如：
<span set-lan="html:name"><i class="icon"></i>名字</span>
// 这样的代码，是无法把“名字”替换成“Name”的，会把“名字”前面的i标签也一起替换掉，如果不想把i标签也替换掉，就要在“名字”外面添加一个标签，改成：
<span><i class="icon"></i><lan set-lan="html:name">名字</lan></span>

// 3、定义3个语言的标识+内容的json字符串

var zh-CN = {
            "name" : "姓名",
            "tel" : "电话",
            "email" : "邮箱",
        };

var zh-TW = {
            "name" : "姓名",
            "tel" : "電話",
            "email" : "郵箱",
        };

var en = {
            "name" : "Name",
            "tel" : "Tel",
            "email" : "Email",
        };
var vi-VN = {
            "name" : "不会越南语",
            "tel" : "看不懂越南语",
            "email" : "越南妹子不错",
        };

// 4、遍历带set-lan属性的标签，进行文本替换
$('[set-lan]').each(function(){
    var me = $(this);
    var a = me.attr('set-lan').split(':');
    var p = a[0];   //文字放置位置
    var m = a[1];   //文字的标识

    //用户选择语言后保存在cookie中，这里读取cookie中的语言版本
    var lan = getCookie('lan');

    //选取语言文字
    switch(lan){
        case 'zh-CN':
            var t = zh-CN[m];  //这里cn[m]中的cn是上面定义的json字符串的变量名，m是json中的键，用此方式读取到json中的值
            break;
        case 'zh-TW':
            var t = zh-TW[m];
            break;
        case 'vi-VN':
            var t = vi-VN[m];
            break;
        default:
            var t = en[m];
    }

    //如果所选语言的json中没有此内容就选取其他语言显示
    if(t==undefined) t = zh-CN[m];
    if(t==undefined) t = en[m];
    if(t==undefined) t = zh-TW[m];
    if(t==undefined) t = vi-VN[m];

    if(t==undefined) return true;//文字放置位置有（html,val等，可以自己添加）
    switch(p){
        case 'html':
            me.html(t);
            break;
        case 'val':
        case 'value':
            me.val(t);
            break;
        default:
            me.html(t);
    }

});

// 5、以上是html中的文字替换，但是写在js中的文字怎么办？ 可以定义一个函数，来读取
function getLan(m) {
    //获取文字
    var lan = getCookie('lan');     //语言版本
    //选取语言文字
    switch(lan){
        case 'zh-CN':
            var t = zh-CN[m];
            break;
        case 'zh-TW':
            var t = zh-TW[m];
            break;
        case 'vi-VN':
            var t = vi-VN[m];
            break;
        default:
            var t = en[m];

    //如果所选语言的json中没有此内容就选取其他语言显示
    if(t==undefined) t = zh-CN[m];
    if(t==undefined) t = en[m];
    if(t==undefined) t = zh-TW[m];
    if(t==undefined) t = vi-VN[m];

    if(t==undefined) t = m; //如果还是没有就返回他的标识

    return t;
}

//遍历dom来修改文字笨了点，能跑就OK 也可以请求后台返回不同语言的文字 
// 反正NGINX 做了语言标识转发到 后台

// 有空了写再后台接受到 nginx 语言 标识 后 多语言操作方式
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xn--6o0a585a.gitbook.io/devops/fu-wu/nginx/nginx-gen-ju-yong-hu-ip-fan-hui-dui-ying-di-qu-yu-yan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
