鍍金池/ 教程/ GO/ 10.1 設(shè)置默認(rèn)地區(qū)
7 文本處理
3 Web基礎(chǔ)
14 擴(kuò)展Web框架
10.4 小結(jié)
2.2 Go基礎(chǔ)
2.8 總結(jié)
6.1 session和cookie
5.5 使用beedb庫進(jìn)行ORM開發(fā)
8.3 REST
13.6 小結(jié)
5.4 使用PostgreSQL數(shù)據(jù)庫
14.6 pprof支持
14.1 靜態(tài)文件支持
11.2 使用GDB調(diào)試
7.7 小結(jié)
1 GO環(huán)境配置
14.5 多語言支持
7.1 XML處理
1.5 總結(jié)
13 如何設(shè)計(jì)一個(gè)Web框架
14.3 表單及驗(yàn)證支持
12 部署與維護(hù)
10 國際化和本地化
1.1 Go 安裝
6.2 Go如何使用session
5.6 NOSQL數(shù)據(jù)庫操作
6.5 小結(jié)
9.4 避免SQL注入
12.1 應(yīng)用日志
4.2 驗(yàn)證表單的輸入
10.1 設(shè)置默認(rèn)地區(qū)
1.3 Go 命令
9.6 加密和解密數(shù)據(jù)
4.1 處理表單的輸入
4.4 防止多次遞交表單
11.3 Go怎么寫測(cè)試用例
8 Web服務(wù)
12.3 應(yīng)用部署
5.7 小結(jié)
12.5 小結(jié)
11 錯(cuò)誤處理,調(diào)試和測(cè)試
9.2 確保輸入過濾
14.2 Session支持
6.4 預(yù)防session劫持
12.4 備份和恢復(fù)
8.1 Socket編程
13.1 項(xiàng)目規(guī)劃
13.4 日志和配置設(shè)計(jì)
7.6 字符串處理
13.2 自定義路由器設(shè)計(jì)
6.3 session存儲(chǔ)
3.4 Go的http包詳解
8.2 WebSocket
10.3 國際化站點(diǎn)
7.5 文件操作
7.4 模板處理
9.1 預(yù)防CSRF攻擊
13.3 controller設(shè)計(jì)
2.6 interface
14.4 用戶認(rèn)證
2.3 流程和函數(shù)
附錄A 參考資料
11.1 錯(cuò)誤處理
9.5 存儲(chǔ)密碼
9.3 避免XSS攻擊
12.2 網(wǎng)站錯(cuò)誤處理
6 session和數(shù)據(jù)存儲(chǔ)
2.4 struct類型
3.3 Go如何使得Web工作
2.5 面向?qū)ο?/span>
3.1 Web工作方式
1.2 GOPATH與工作空間
2.1 你好,Go
9.7 小結(jié)
13.5 實(shí)現(xiàn)博客的增刪改
7.2 JSON處理
10.2 本地化資源
7.3 正則處理
2 Go語言基礎(chǔ)
5.1 database/sql接口
4.5 處理文件上傳
8.5 小結(jié)
4.3 預(yù)防跨站腳本
5.3 使用SQLite數(shù)據(jù)庫
14.7 小結(jié)
3.2 Go搭建一個(gè)Web服務(wù)器
2.7 并發(fā)
5 訪問數(shù)據(jù)庫
4 表單
3.5 小結(jié)
1.4 Go開發(fā)工具
11.4 小結(jié)
9 安全與加密
5.2 使用MySQL數(shù)據(jù)庫
4.6 小結(jié)
8.4 RPC

10.1 設(shè)置默認(rèn)地區(qū)

什么是Locale

Locale是一組描述世界上某一特定區(qū)域文本格式和語言習(xí)慣的設(shè)置的集合。locale名通常由三個(gè)部分組成:第一部分,是一個(gè)強(qiáng)制性的,表示語言的縮寫,例如"en"表示英文或"zh"表示中文。第二部分,跟在一個(gè)下劃線之后,是一個(gè)可選的國家說明符,用于區(qū)分講同一種語言的不同國家,例如"en_US"表示美國英語,而"en_UK"表示英國英語。最后一部分,跟在一個(gè)句點(diǎn)之后,是可選的字符集說明符,例如"zh_CN.gb2312"表示中國使用gb2312字符集。

GO語言默認(rèn)采用"UTF-8"編碼集,所以我們實(shí)現(xiàn)i18n時(shí)不考慮第三部分,接下來我們都采用locale描述的前面兩部分來作為i18n標(biāo)準(zhǔn)的locale名。

在Linux和Solaris系統(tǒng)中可以通過locale -a命令列舉所有支持的地區(qū)名,讀者可以看到這些地區(qū)名的命名規(guī)范。對(duì)于BSD等系統(tǒng),沒有l(wèi)ocale命令,但是地區(qū)信息存儲(chǔ)在/usr/share/locale中。

設(shè)置Locale

有了上面對(duì)locale的定義,那么我們就需要根據(jù)用戶的信息(訪問信息、個(gè)人信息、訪問域名等)來設(shè)置與之相關(guān)的locale,我們可以通過如下幾種方式來設(shè)置用戶的locale。

通過域名設(shè)置Locale

設(shè)置Locale的辦法這一就是在應(yīng)用運(yùn)行的時(shí)候采用域名分級(jí)的方式,例如,我們采用www.asta.com當(dāng)做我們的英文站(默認(rèn)站),而把域名www.asta.cn當(dāng)做中文站。這樣通過在應(yīng)用里面設(shè)置域名和相應(yīng)的locale的對(duì)應(yīng)關(guān)系,就可以設(shè)置好地區(qū)。這樣處理有幾點(diǎn)好處:

  • 通過URL就可以很明顯的識(shí)別
  • 用戶可以通過域名很直觀的知道將訪問那種語言的站點(diǎn)
  • 在Go程序中實(shí)現(xiàn)非常的簡單方便,通過一個(gè)map就可以實(shí)現(xiàn)
  • 有利于搜索引擎抓取,能夠提高站點(diǎn)的SEO

我們可以通過下面的代碼來實(shí)現(xiàn)域名的對(duì)應(yīng)locale:

if r.Host == "www.asta.com" {
    i18n.SetLocale("en")
} else if r.Host == "www.asta.cn" {
    i18n.SetLocale("zh-CN")
} else if r.Host == "www.asta.tw" {
    i18n.SetLocale("zh-TW")
}

當(dāng)然除了整域名設(shè)置地區(qū)之外,我們還可以通過子域名來設(shè)置地區(qū),例如"en.asta.com"表示英文站點(diǎn),"cn.asta.com"表示中文站點(diǎn)。實(shí)現(xiàn)代碼如下所示:

prefix := strings.Split(r.Host,".")

if prefix[0] == "en" {
    i18n.SetLocale("en")
} else if prefix[0] == "cn" {
    i18n.SetLocale("zh-CN")
} else if prefix[0] == "tw" {
    i18n.SetLocale("zh-TW")
}

通過域名設(shè)置Locale有如上所示的優(yōu)點(diǎn),但是我們一般開發(fā)Web應(yīng)用的時(shí)候不會(huì)采用這種方式,因?yàn)槭紫扔蛎杀颈容^高,開發(fā)一個(gè)Locale就需要一個(gè)域名,而且往往統(tǒng)一名稱的域名不一定能申請(qǐng)的到,其次我們不愿意為每個(gè)站點(diǎn)去本地化一個(gè)配置,而更多的是采用url后面帶參數(shù)的方式,請(qǐng)看下面的介紹。

從域名參數(shù)設(shè)置Locale

目前最常用的設(shè)置Locale的方式是在URL里面帶上參數(shù),例如www.asta.com/hello?locale=zh或者www.asta.com/zh/hello。這樣我們就可以設(shè)置地區(qū):i18n.SetLocale(params["locale"])。

這種設(shè)置方式幾乎擁有前面講的通過域名設(shè)置Locale的所有優(yōu)點(diǎn),它采用RESTful的方式,以使得我們不需要增加額外的方法來處理。但是這種方式需要在每一個(gè)的link里面增加相應(yīng)的參數(shù)locale,這也許有點(diǎn)復(fù)雜而且有時(shí)候甚至相當(dāng)?shù)姆爆?。不過我們可以寫一個(gè)通用的函數(shù)url,讓所有的link地址都通過這個(gè)函數(shù)來生成,然后在這個(gè)函數(shù)里面增加locale=params["locale"]參數(shù)來緩解一下。

也許我們希望URL地址看上去更加的RESTful一點(diǎn),例如:www.asta.com/en/books(英文站點(diǎn))和www.asta.com/zh/books(中文站點(diǎn)),這種方式的URL更加有利于SEO,而且對(duì)于用戶也比較友好,能夠通過URL直觀的知道訪問的站點(diǎn)。那么這樣的URL地址可以通過router來獲取locale(參考REST小節(jié)里面介紹的router插件實(shí)現(xiàn)):

mux.Get("/:locale/books", listbook)

從客戶端設(shè)置地區(qū)

在一些特殊的情況下,我們需要根據(jù)客戶端的信息而不是通過URL來設(shè)置Locale,這些信息可能來自于客戶端設(shè)置的喜好語言(瀏覽器中設(shè)置),用戶的IP地址,用戶在注冊(cè)的時(shí)候填寫的所在地信息等。這種方式比較適合Web為基礎(chǔ)的應(yīng)用。

  • Accept-Language

客戶端請(qǐng)求的時(shí)候在HTTP頭信息里面有Accept-Language,一般的客戶端都會(huì)設(shè)置該信息,下面是Go語言實(shí)現(xiàn)的一個(gè)簡單的根據(jù)Accept-Language實(shí)現(xiàn)設(shè)置地區(qū)的代碼:

AL := r.Header.Get("Accept-Language")
if AL == "en" {
    i18n.SetLocale("en")
} else if AL == "zh-CN" {
    i18n.SetLocale("zh-CN")
} else if AL == "zh-TW" {
    i18n.SetLocale("zh-TW")
}

當(dāng)然在實(shí)際應(yīng)用中,可能需要更加嚴(yán)格的判斷來進(jìn)行設(shè)置地區(qū)

  • IP地址

    另一種根據(jù)客戶端來設(shè)定地區(qū)就是用戶訪問的IP,我們根據(jù)相應(yīng)的IP庫,對(duì)應(yīng)訪問的IP到地區(qū),目前全球比較常用的就是GeoIP Lite Country這個(gè)庫。這種設(shè)置地區(qū)的機(jī)制非常簡單,我們只需要根據(jù)IP數(shù)據(jù)庫查詢用戶的IP然后返回國家地區(qū),根據(jù)返回的結(jié)果設(shè)置對(duì)應(yīng)的地區(qū)。

  • 用戶profile

    當(dāng)然你也可以讓用戶根據(jù)你提供的下拉菜單或者別的什么方式的設(shè)置相應(yīng)的locale,然后我們將用戶輸入的信息,保存到與它帳號(hào)相關(guān)的profile中,當(dāng)用戶再次登陸的時(shí)候把這個(gè)設(shè)置復(fù)寫到locale設(shè)置中,這樣就可以保證該用戶每次訪問都是基于自己先前設(shè)置的locale來獲得頁面。

總結(jié)

通過上面的介紹可知,設(shè)置Locale可以有很多種方式,我們應(yīng)該根據(jù)需求的不同來選擇不同的設(shè)置Locale的方法,以讓用戶能以它最熟悉的方式,獲得我們提供的服務(wù),提高應(yīng)用的用戶友好性。

上一篇:13.6 小結(jié)下一篇:14.6 pprof支持