原文:www.w3.org/Internation…javascript
language+region:特定地區的語言(例如:en-US, zh-HK)html
vanilla language:父語言(例如:en, zh)java
例如:en-US【英語-美國】/ en-GB【英語-英國】/ en-CA【英語-加拿大】的 vanilla language 是 en;zh-HK 【中文-香港】/ zh-TW【中文-臺灣】/ zh-CN【中文-簡體】 的 vanilla language 是 zh。apache
怎樣經過瀏覽器的語言設置去指定服務器返回的內容的語言?npm
大多數桌面瀏覽器有查看和修改語言首選項的設置,這些設置告訴服務器用戶傾向於使用什麼語言展現頁面和資源(注意和瀏覽器界面語言區分)。然而,對於移動設備的瀏覽器,語言首選項更可能是由操做系統的語言設置決定的,或者在某些狀況下由下載瀏覽器時的系統語言決定的。json
容許用戶修改語言首選項的瀏覽器一般也會容許用戶指定多個語言首選項,這樣一旦第一選擇的語言不能被知足的時候就會按序使用後面的語言選項。windows
若是您的瀏覽器設置成請求特定地區的語言,例如:zh-HK (香港地區使用的中文),則應確保緊隨其後指定一個 vanilla language,例如:zh。瀏覽器
您可使用 Internationalization Checker 查看瀏覽器發送請求時攜帶的語言偏好信息。服務器
多數狀況下,瀏覽器的初始設置就能知足您的需求。例如:若是您的瀏覽器是日文版的,瀏覽器一般會假定您偏好使用日文展現頁面而且在發送請求的時候帶上偏好日文這個信息。下面詳細講解如何修改語言首選項。post
當瀏覽器從 Web 服務器拉取文檔時,它會向存儲信息的服務器發送請求,即 HTTP 請求。在這個請求中,瀏覽器會發送它的語言首選項。
瀏覽器經過 Accept-Language 請求頭髮送語言首選項,若是請求的頁面在服務器有多種語言版本,而且偏好的語言版本也存在,就會經歷一個 HTTP 內容協商 的過程來找到並返回偏好的版本。 若是服務器上只有一個語言版本,則返回該版本。 若是請求的語言版本都不存在,則返回服務器設置的默認語言版本。
大多數主流瀏覽器容許修改 HTTP 請求頭的語言首選項,它的值應該符合 BCP 47 規範 (Tags for the Identification of Languages) ,一般是兩個或三個字母的語言代碼(例如,fr 表明法語),其後是表明國家或區域的可選子代碼(例如,fr-CA 表明加拿大使用的法語;es-419 表明拉丁美洲使用的西班牙語)。更多語言標記請參考 language tags。
當瀏覽器的語言首選項設置了多種語言,瀏覽器會按序爲其設置一個從大至小的權重值,以幫助服務器明白您的偏好語言。下面是一個 Accept-Language 具備多個語言值的例子:da 是首選,若是不可用,就返回 en-gb,還不可用就返回 en 版本(例如,en-US, en-CA, en-DE 等等)。
Accept-Language: da,en-gb;q=0.8, en;q=0.7
複製代碼
您一般能夠指定幾個可選語言,它們是有順序的。以下圖是 FireFox 中的語言首選項設置,其中:French/Switzerland [fr-ch] 是首選,若是不可用的話,會依照 French [fr], German [de], English [en] 的順序請求。
爲確保服務器能返回您最偏好的語言版本,您應該在瀏覽器中按照 language+region, vanilla language 這樣的順序配置(例如,fr-CH -> fr)。這樣能確保服務器先尋找 fr-CH 版本,若是不可用的話,再去尋找任意 French 版本,而後是 German 版本。由於首選項是 Swiss French,因此在首選項不可用的狀況下,固然 French 是比 German 更好的選擇,由於它至少仍是 French。
Chrome 會自動爲指定區域或國家的語言標記添加一個任意版本(例如,爲 zh-CN 添加 zh),即便在語言首選項設置中沒有顯示列出來。可是大多數瀏覽器都不會這麼作,因此最好仍是先檢查當前的 Accept-Language 的值,看有沒有自動加上任意版本,若是沒有的話,手動去語言首選項設置中添加一個任意版本。
在修改語言首選項以前,您可能想先看看當前 Accept-Language 的值。運行 Internationalization Checker,輸入任意一個 URL,查看 Request Headers -> Accept-Language。見 demo。
咱們在此列出瞭如何更改 Windows 或 OS X 桌面平臺上許多流行瀏覽器的最新版本的語言首選項的示例。 咱們在撰寫本文時使用了這些瀏覽器的最新版本。
對於大多數移動設備,語言首選項是由系統的第一語言決定的,沒法單獨設置。
Edge
在設置頁打開 Regions & language,選擇 option 添加一個語言 language+region / vanilla language。
選好以後,能夠在語言列表中調整順序或刪除某個語言。
重啓 Edge。
若是您手動添加了一個 language+region 的語言,Edge 會自動緊隨其後添加一個 vanilla language,可是不會在語言列表中顯示它。例如,若是您手動添加了 en-US,Edge 會在其後隱式添加一個 en,但您只會在在語言列表中看到 en-US,不會看到 en。此時,若是您再手動添加一個 en-GB,那麼最終的語言列表順序是 en-US -> en-GB -> en,而且您在語言列表中只會看到 en-US -> en-GB。
Chrome
若是您添加了一個 language+region 的語言,Chrome 會自動緊隨其後添加一個 vanilla language。例如,若是您手動添加了 en-US,Chrome 會在其後隱式添加一個 en,此時,若是您再手動添加一個 en-GB,那麼最終的語言列表順序是 en-US -> en -> en-GB,您須要手動將 en-GB 調整到 en 的前面。
Firefox
若是您添加了一個 language+region 的語言,Firefox 就只會添加它,不會自動添加它的 vanilla language,您須要本身緊隨其後手動添加它的 vanilla language。例如,若是您手動添加了 en-US,Firefox 不會自動添加 en,您須要手動添加 en,若是您再添加一個 en-GB,那麼最終的語言列表順序是 en-US -> en -> en-GB,您須要手動將 en-GB 調整到 en 的前面。
Safari
爲何須要 language+region 和 vanilla language 成對按序出現?
若是您的添加的語言是 language+region(例如,fr-CH),您應該緊隨其後添加一個它對應的 vanilla language(例如,fr)。
這是由於若是服務器遵循的是 HTTP/1.1 規範,而且有 fr 版本,沒有 fr-CH 版本,當 Accept-Language 爲 fr-CH,服務器在沒法提供 fr-CH 版本的狀況下也沒法返回 fr 版本。
在實際應用中,Apache 服務器遇到上述狀況時仍是會返回 fr 版本文檔,這是由於它隱式地在語言首選項列表中添加了一個 fr 語言。可是,隱式添加的 fr 權重很低,若是您的語言首選項列表只包含一種語言,Apache 服務器會正確返回 vanilla language 版本;若是您指定了多個語言,則極可能會遇到問題。Apache documentation 是這樣解釋的:
Apache 會隱式地將 vanilla language 添加到客戶端的語言首選項列表中,可是權重很低。若是 Accept-Language
是 "en-GB; q=0.9, fr; q=0.8",服務器有 en 版本和 fr 版本,那麼當 en-GB 不可用時,即便隱式添加了 en,
但因爲權重低於 fr,服務器仍是會返回 fr 版本。
複製代碼
咱們來看一個例子,假定 Apache 服務器除了 French/Switzerland [fr-ch] 版本沒有,其餘版本都有,根據右圖中的首選項列表,Apache 服務器老是返回 fr 版本,由於 French[fr] 的權重第二高。若是咱們移除 fr,如左圖,儘管 Apache 服務器會隱式的添加一個 French[fr],但因爲它的權重是低於 German[de] 的,因此服務器會返回 German[de] 版本。
內容協商
操做系統語言設置 VS 瀏覽器語言設置 VS 瀏覽器界面語言
操做系統語言設置:在【語言和地區】選項中設置的語言,MAC OSX 能夠在 系統偏好設置 -> 語言和地區 中設置,windows 能夠在控制面板中設置。
瀏覽器語言設置: Accept-Language 的值,能夠經過 navigator.languages 獲取。
瀏覽器界面語言: 瀏覽器界面(菜單欄 / 地址欄等)顯示的語言。
[譯文]一步步構建發佈一個 TypeScript NPM 包