什么是多語言?
我們平時訪問一些文檔類型的網(wǎng)站時盼理,經(jīng)程干剑可以看到頁面右上角有一個下拉框用來選擇當(dāng)前頁面支持的語言,并在選中后將整個網(wǎng)頁的內(nèi)容切換為選中的語言宏怔,這就是項目中的多語言奏路,多語言可以根據(jù)瀏覽器請求發(fā)送的語言類型在服務(wù)器進(jìn)行設(shè)置,也可以在請求服務(wù)器時返回多種語言臊诊,并根據(jù)權(quán)重和瀏覽器的支持情況進(jìn)行選擇和渲染鸽粉。
功能描述
在本文中我們通過客戶端向服務(wù)器發(fā)送請求告訴服務(wù)器客戶端所支持的語言及權(quán)重,服務(wù)器檢索語言包并根據(jù)客戶端發(fā)送的語言類型和權(quán)重返回對應(yīng)語言的內(nèi)容抓艳。
在這個過程中客戶端向服務(wù)器發(fā)送請求需要使用請求頭 Accept-Language
触机,值中設(shè)置語言類型和權(quán)重,語言與語言之間使用 ,
隔開,語言與權(quán)重之間使用 ;
隔開儡首,權(quán)重用 q
表示片任,與值用 =
隔開,如果權(quán)重值為 1
則可省略(最大值)蔬胯,值的格式為 zh-CN, zh;q=0.7, en;q=0.8, fr;q=0.1
对供。
服務(wù)器響應(yīng)時,應(yīng)通過響應(yīng)頭告訴瀏覽器返回的內(nèi)容為何種語言笔宿,響應(yīng)頭為 Content-Language
, 值的格式為 zh-CN, en
犁钟,多個語言之間使用 ,
隔開。
服務(wù)器的實現(xiàn)
// 文件:server.js
const http = require("http");
const querystring = require("querystring");
// 語言包
let languagesPackage = {
"zh-CN": "你好",
en: "Hello",
fr: "Bonjour"
};
// 默認(rèn)語言為英語
languagesPackage.defaultLanguage = "en";
// 創(chuàng)建服務(wù)器
const server = http.createServer((req, res) => {
// 獲取請求頭中的語言和權(quán)重
let languages = req.headers["accept-language"];
// 如果客戶端設(shè)置了語言
if (languages) {
// 解析語言為 [{ name: 'zh-CN', q: 1 }, { name: 'en', q: '0.8' }] 格式
let lans = languages
.split(",")
.map(lang => {
let [name, q = 1] = Object.keys(
querystring.parse(lang.tirm(), ";q=")
);
return { name, q };
})
.sort((a, b) => b.q - a.q); // 并按照權(quán)重逆序排序
// 循環(huán)檢測 languagesPackage 是否存在客戶端的語言
for (let i = 0; i < lans.length; i++) {
let { name } = lans[i];
let content = languagesPackage[name];
// 如果存在直接設(shè)置響應(yīng)頭并返回內(nèi)容
if (content) {
res.setHeader("Content-Type", name);
return res.end(content);
}
}
}
// 如果客戶端沒設(shè)置語言活語言找不到時返回服務(wù)器設(shè)置的默認(rèn)語言
res.setHeader("Content-Type", languagesPackage.defaultLanguage);
res.end(languagesPackage[languagesPackage.defaultLanguage]);
});
server.listen(3000, () => {
console.log("server start 3000");
});
其實上面服務(wù)器和客戶端配合實現(xiàn)多語言的思路就是客戶端向服務(wù)器發(fā)送 Accept-Language
告訴服務(wù)器需要的語言和權(quán)重泼橘,服務(wù)器解析后根據(jù)權(quán)重從大到小排序涝动,然后循環(huán)判斷語言包中是否含有客戶端需要的語言,如果有炬灭,則中斷循環(huán)直接設(shè)置響應(yīng)頭和返回對應(yīng)內(nèi)容醋粟,如果不存在客戶端的需要的語言或者客戶端沒有向后臺發(fā)送 Accept-Language
則返回服務(wù)器默認(rèn)設(shè)置的語言類型和內(nèi)容。
驗證多語言
為了方便我們使用 curl
模擬客戶端向服務(wù)器發(fā)送請求查看返回內(nèi)容是否正確重归,之所以使用 curl
是因為只發(fā)送驗證的請求米愿,方便設(shè)置 Accept-Language
請求頭,更靈活的控制多語言的類型和權(quán)重鼻吮。
啟動服務(wù)器 server.js
育苟,打開命令行窗口,輸入下面的命令執(zhí)行椎木,查看返回命令行響應(yīng)體中的內(nèi)容和設(shè)置的語言是否對應(yīng)违柏。
curl -v --header “Accept-Language: zh-CN, zh;q=0.7, en;q=0.8, fr;q=0.1” http://localhost:3000
總結(jié)
這樣我們就實現(xiàn)了一個簡單的多語言,其實真正的多語言在服務(wù)器是需要做繁瑣的解析和性能優(yōu)化的(只解析界面有的單詞返回香椎,保證響應(yīng)體中的內(nèi)容最惺),在前端可以通過 JavaScript 的庫 il8n
(國際化語言包)來實現(xiàn)畜伐。