標籤:des style blog http color 使用 os io
我們會看到很多支援多語言的網站,有些早期的網站在首頁會有一個連結,讓使用者自己來選希望看到中文,還是英文,現在的網站則不需要了,這些網站可以根據使用者使用的語言來顯示不同語言的版本。比如,你在使用簡體中文,開啟網頁,會看到一個簡體中文的網頁,你在使用英文,輸入同一個地址,就會看到一個英文的頁面。
伺服器是如何知道使用者希望看到何種語言版本的頁面呢?
瀏覽器端
對於網站來說,一個網站要服務海量的使用者,使用伺服器來記住使用者的語言是很麻煩的,這個工作還是從瀏覽器開始,如果瀏覽器自己告訴伺服器希望使用的語言,伺服器不就簡單了嗎?
各種瀏覽器都可以設定希望使用的語言,在 IE 中,選擇設定,彈出對話方塊之後,可以設定語言喜好設定。
點擊語言,彈出語言喜好設定對話方塊。
在控制台中進行設定。
對於 Chrome 來說,在進階設定中。
點擊語言和輸入設定。
當瀏覽器向伺服器發出請求的時候,瀏覽器會在要求標頭中添加一個特殊的要求標頭 Accept-Language 來說明瀏覽器端設定的語言類型,如果你剛才注意的話,會發現我們可以設定多個語言,而且可以調整順序,在 Accept-Language 頭中,它們按著你設定的順序依次出現。每種語言使用逗號 (,) 進行分隔。
各種瀏覽器的 Accept-Language 如下所示。
IE 的語言
Accept-Language en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3
Chrome 的語言
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
FireFox 的語言
Accept-Language: en-us,zh-cn;q=0.8,en;q=0.5,zh;q=0.3
慢著,q 又是什麼呢?在 HTTP 協議中有一個詳細的說明,點擊這裡的連結可以查看詳細說明: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html。簡單來說,語言可以攜帶一個“q”值,來表示使用者對該語言的喜好程度,這個值在 0 - 1 之間,預設為 1。
伺服器端
在我們伺服器端代碼中,可以直接擷取到瀏覽器在請求中攜帶的語言設定,在 .NET 中,HttpRequest 表示瀏覽器發出的請求,屬性 UserLanguages 就表示 Accept-Language 中傳遞的語言,已經根據優先順序進行了排序,而且已經根據逗號 (,) 進行了拆分。這個屬性是一個字串數組。
代碼中
string[] languages = Request.UserLanguages;
比如,我們希望取出第一個語言,就可以通過 Request.UserLanguages[0] 來擷取到了。
擷取的語言從程式的角度來說僅僅是一個表示語言的字串,從物件導向的角度來說,我們需要一個對象來表示語言,這個類就是 CurtureInfo 類,它定義在命名空間 System.Globalization 中。可以通過 MSDN 來查看它的定義。
通常,我們將表示語言的字串通過建構函式傳遞給 CultureInfo。
CultureInfo info = new CultureInfo(culture);
中文問題
如果你剛才仔細查看的話,會發現 IE 發送的語言代碼與 Chrome 是不一樣的。你會發現表示簡體中文實際上有四種寫法:
- zh
- zh-cn
- zh-Hans
- zh-Hans-CN
這些寫法是從哪裡來的呢,在 MSDN 中有詳細的說明
CultureInfo 類將根據 RFC 4646 為每個地區性指定一個唯一的名稱。 名稱是語言關聯的 ISO 639 小寫雙字母地區性代碼和省/地區關聯的 ISO 3166 大寫雙字母子領域性代碼的組合。
比如 zh 就表示中文,Han: 漢字 ,S: Simplified 簡體字,T: Tranditional 繁體字,而 cn 表示中國地區代碼。
地區性名稱的格式為 兩個小寫字元的語言代碼>-兩個大寫字元的國家地區碼。 例如 “zh-CN” 代表“中文(簡體中文)”,“en-US”代表“英語(美國)”。 在雙字母語言代碼停用情況中,將使用從 ISO 639-2 派生的三字母代碼。
請注意,某些地區性名稱還指定 ISO 15924 書寫符號。 例如,中文有簡體和繁體之分,這種名稱可以使用 兩字元的語言碼-書寫標記-兩字元的國家地區碼形式。 例如“zh-Hans-CN”代表“簡體中文(中國)”。 對於 Windows Vista 之前的作業系統,包含書寫符號的地區性名稱使用languagecode2-country/regioncode2-scripttag 的模式,例如“uz-UZ-Cyrl”代表“烏茲別克語(烏茲別克,西裡爾語)”。
非特定地區性只能由雙字母小寫語言代碼指定。 例如,fr指定“法語”的非特定地區性,de指定“德語”的非特定地區性。
那麼,zh 就表示非特定地區的中文,en 就表示非特定地區的英文。
但是,需要注意的是,CultureInfo 不支援 zh-Hans-CN 寫法,如果你使用了,會收到這樣一個異常。
zh-Hans-CN 是無效的地區性標識符。
你可以使用 zh, zh-cn, zh-Hans, 但是,不能使用 zh-Hans-CN 來構建 CultureInfo 對象。