fbpx

網站如何自動偵測語系跳轉頁面

international-mother-language-day_21213
來源 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 惹!

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 的重導問題,對於大型的分散式架構也可以正確執行。

 

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 才會比較友善喔。如下:

<link rel="alternate" hreflang="x-default" href="http://domain.com/" />
<link rel="alternate" hreflang="zh-TW" href="http://domain.com/zh-TW/" />
<link rel="alternate" hreflang="zh-CN" href="http://domain.com/zh-CN/" />
<link rel="alternate" hreflang="en-US" href="http://domain.com/en-US/" />
<link rel="alternate" hreflang="zh" href="http://domain.com/zh-CN/" />
<link rel="alternate" hreflang="en" href="http://domain.com/en-US/" />

收工!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料