Zi 字媒體
2017-07-25T20:27:27+00:00
來源 http://www.filcatholic.org/
早期網站或服務對於各種語言的使用者,在首頁都會出現一個選擇語系的畫面,這樣的設計已經非常過時,使用體驗很差。現在很多網站都是使用單一網址,當使用者進到網頁後,程式會自動判定瀏覽器所設定的語系進行轉頁,原理其實是透過判斷 HTTP Request 中的 Accept-Language Header 設定來實現,詳細規範可以參考 RFC-2616 (14.4 Accept-Language) 章節。
那麼如何設計自動判定語系跳轉頁面的功能呢?假設我們不同語系的入口網址設計如下:
繁體中文:http://domain.com/zh-TW/
簡體中文:http://domain.com/zh-CN/
預設英文:http://domain.com/en-US/
要實現判斷使用者語系自動跳轉網頁有兩種方法,一種為不需要 HTTP Server 的設定,直接透過 JavaScript 進行跳轉。範例程式碼如下 (GitHub),可以把這樣的程式放在 index.html 首頁,使用者進入厚就會自動跳轉,由於是透過 JavaScript 實現,如果 JavaScript 功能被關閉當然就 GG 惹!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
try {
var switchPage = function (language) {
switch (language) {
case 'zh-cn':
console.log('/zh-CN' + window.location.pathname);
window.location.href = '/zh-CN' + window.location.pathname;
return true;
break;
case 'zh':
case 'zh-tw':
console.log('/zh-TW' + window.location.pathname);
window.location.href = '/zh-TW' + window.location.pathname;
return true;
break;
case 'en':
case 'en-us':
console.log('/en-US' + window.location.pathname);
window.location.href = '/en-US' + window.location.pathname;
return true;
break;
default:
}
return false;
};
// detect window.navigator.languages
var found = false;
if (typeof(window.navigator.languages) === 'object') {
for (var index in window.navigator.languages) {
console.log(window.navigator.languages[index].toLowerCase());
found = switchPage(window.navigator.languages[index].toLowerCase());
if (found) break;
}
}
if (!found) {
var lang = window.navigator.userLanguage || window.navigator.language;
var relang = lang.toLowerCase();
found = switchPage(relang);
}
if (!found) {
window.location.href = '/en-US' + window.location.pathname;
}
} catch (e) {
window.location.href = '/en-US' + window.location.pathname;
}
上述使用 JavaScript 轉頁的方法雖然比較簡單,但是對於 SEO (搜尋引擎最佳化) 是比較不友善的做法,因為首頁 index.html 變成一個只能專門用來跳轉頁面的程式碼,對於搜尋引擎 Index 的建立與搜尋結果都不佳。
再來介紹第二種方法,透過 HTTP Server 判定 Header 來跳轉,這樣的方法不需要在 http://domain.com 回傳任何,僅需要送出正確的 302 讓瀏覽器自動跳轉即可,這樣的方法對於搜尋引擎是最友善的,可以正確的在不同國家顯示對應的搜尋結果。
以 Nginx 為例 (有好一陣子沒用 Apache 了),可以在設定檔中加入以下設定 (GitHub),這個版本已經有考慮 Request 透過 Proxy 的重導問題,對於大型的分散式架構也可以正確執行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
server {
...
# detect Accept-Language auto redirect to langauge path
location = / {
# Setup language prefix
set $prefix_language $http_accept_language;
if ($http_accept_language ~* '^(.+?),') {
set $prefix_language $1;
}
# Setup redirect Schema
set $redirect_schema $scheme;
if ($http_X_Forwarded_Proto = 'https') {
set $redirect_schema $http_X_Forwarded_Proto;
}
# Setup redirect Host
set $redirect_host $host;
if ($http_X_Forwarded_Host != '') {
set $redirect_host $http_X_Forwarded_Host;
}
# Setup URL
set $lang_url $redirect_schema://$redirect_host;
if ($prefix_language ~* 'zh-TW') {
return 302 $lang_url/zh-TW/;
}
if ($prefix_language ~* 'zh-CN') {
return 302 $lang_url/zh-CN/;
}
# Default en-US
return 302 $lang_url/en-US/;
}
}
這樣一來,當使用者連線到 http://domain.com 就會自動偵測 HTTP Header 然後回應 302 讓瀏覽器跳轉,測試的時候要注意,由於瀏覽器通常都會有 Cache 機制,比較保險的測試方式可以透過以下 CURL 命令來模擬瀏覽器發送封包,確認設定後 Server 回應封包是正確的。
curl 'http://domain.com/' -H 'Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4' -v
最後提醒一下,不同語系頁面的 HTML 記得在 Head Tag 標註各種語系的 hreflang 設定 URL,SEO 才會比較友善喔。如下:
1
2
3
4
5
6
rel="alternate" hreflang="x-default" href="http://domain.com/" />
rel="alternate" hreflang="zh-TW" href="http://domain.com/zh-TW/" />
rel="alternate" hreflang="zh-CN" href="http://domain.com/zh-CN/" />
rel="alternate" hreflang="en-US" href="http://domain.com/en-US/" />
rel="alternate" hreflang="zh" href="http://domain.com/zh-CN/" />
rel="alternate" hreflang="en" href="http://domain.com/en-US/" />
收工!
分享到 Twitter(在新視窗中開啟)
按一下以分享至 Facebook(在新視窗中開啟)
分享到 LinkedIn(在新視窗中開啟)
點這裡寄給朋友(在新視窗中開啟)
按一下即可分享至 Skype(在新視窗中開啟)
分享到 Reddit(在新視窗中開啟)
分享到 Tumblr(在新視窗中開啟)
按一下以分享到 Telegram(在新視窗中開啟)
寫了
5860316篇文章,獲得
23313次喜歡