在 OpenResty Edge 中根據瀏覽器語言重定向,只需建立一條頁面規則,同時匹配請求 URI / 客戶端傳送的 Accept-Language 請求頭,再掛上一個跳轉到對應語言路徑(如 /fr/)的重定向動作。把它標記為置頂規則讓它最先執行,再加一條兜底規則把其他所有語言都跳到 /en/。配置會下發到每個閘道器節點,無需伺服器過載、重啟或二進位制升級。

下面我們在 OpenResty Edge 的 Admin 控制檯裡一步步建立這兩條規則,並用 curl 和瀏覽器驗證。如果你想先看一個更簡單的規則,可以參考如何用 301 頁面規則將 HTTP 重定向到 HTTPS

示意圖:OpenResty Edge 根據 Accept-Language 頭把訪客重定向到對應語言的 URI

按路徑提供多語言的源站

假設我們有一個支援在不同路徑下展示不同語言的源站。例如,這是 /en/ 路徑。

$ curl 'http://test-edge.com/en/'
Hello, world!

注意這裡是英文, “Hello, world!”。

/fr/ 路徑下還有一個法語版本。

$ curl 'http://test-edge.com/fr/'
Bonjour, le monde!

這裡顯示的是法語。

建立頁面規則按 Accept-Language 重定向

今天設定的目標是,當客戶端訪問根路徑 / 時,我們可以根據其語言配置自動重定向到特定語言的路徑下。我們將使用客戶端傳送的 Accept-Language 請求頭。

OpenResty Edge 根據 Accept-Language 頭將根路徑重定向到對應語言路徑

像往常一樣,讓我們進入 OpenResty Edge 的 Admin Web 控制檯。這是我們控制檯的樣本部署。每個使用者都有自己的本地部署。

這一次我們繼續使用 test-edge.com 域名的樣本應用。

進入這個應用。

在 OpenResty Edge Admin 控制檯中進入 test-edge.com 應用

我們已經定義了一個上游。

應用中已定義的 my_backend 上游

這個 my backend 上游只有一個後端伺服器。也就是我們在影片開頭使用的源站。

my_backend 上游只有一個指向源站的後端伺服器

而且我們也有一個已經定義好的頁面規則。

應用現有的頁面規則列表

這個頁面規則設定了一個反向代理到我們剛才看到的 my backend 上游。

現有頁面規則配置為到 my_backend 上游的反向代理

建立一個新的頁面規則。

在 OpenResty Edge 控制檯中建立新的頁面規則

我們啟用一個規則條件來檢查 URI /

啟用規則條件以匹配請求 URI

這個下拉框裡列出了所有我們可以選擇的變數。

頁面規則條件可選的變數列表

選擇變數 URI

為條件選擇 URI 變數

運算子選擇字串等號。

為 URI 條件選擇字串等號運算子

URI 條件已選定字串等號運算子

輸入值 /,表示只匹配根路徑。

輸入 / 作為值,只匹配根路徑

第二個條件用來檢查語言。

新增檢查請求語言的第二個條件

為語言條件選擇變數

我們選擇 Request header 作為變數。

為語言條件選擇 Request header 變數

輸入請求頭名稱 Accept-Language

輸入要匹配的請求頭名稱 Accept-Language

運算子這裡,

開啟 Accept-Language 條件的運算子列表

我們選擇“字首”。

為 Accept-Language 請求頭選擇字首運算子

這表示當同時指定多種語言時,我們只關心第一種。

我們選擇正規表示式型別 Regex 作為匹配的值。

為 Accept-Language 值選擇 Regex 正則匹配型別

Accept-Language 值已選定 Regex 匹配型別

輸入正則值 fr\b

輸入正則 fr\b 以匹配 fr、fr-CA 等法語標籤

\b 的意思是匹配一個詞的邊界。這樣寫 frfr-CA 都會匹配得到。

這裡,我們勾選“忽略大小寫”以進行不區分大小寫的匹配。

勾選忽略大小寫,對 Accept-Language 做不區分大小寫匹配

現在我們有了以 AND 相連線的兩個條件。也就是說,必須同時滿足這兩個條件,才能執行下面的動作。已經完成條件的編寫。

現在我們新增一個新的動作。

為頁面規則新增新的動作

搜尋動作“重定向”。

選擇動作型別“重定向”。

選擇重定向動作型別

然後我們配置跳轉到的目標 URI 。

配置重定向動作的目標 URI

選擇“自定義”。我們要自己輸入 URI 。

為重定向選擇自定義目標 URI

輸入 /fr/

輸入 /fr/ 作為法語訪客的重定向目標

保持其餘欄位不動。

其餘重定向欄位保持預設

如果命中此條規則的話跳過所有餘下的頁面規則。

啟用命中即跳過後續規則

我們需要確保這條規則總是在其他規則之前執行。我們把它標記為一個置頂規則。置頂規則不是一個普通規則。

將規則標記為置頂規則,使其先於普通規則執行

儲存這個規則。

儲存法語 Accept-Language 重定向規則

我們可以看到新新增的頁面規則確實置頂在規則列表。

新的重定向規則出現在頁面規則列表頂部

它確實出現在我們之前的代理規則之前。

和以往一樣, 我們需要釋出這條規則以使其生效。

釋出新配置以下發該頁面規則

將新配置釋出到各閘道器叢集

釋出!

配置釋出已同步到所有閘道器叢集

這裡可以看到同步完成了。

新頁面規則已推送到每個閘道器叢集和伺服器

現在,新的頁面規則已經被推送到所有的閘道器叢集和伺服器。

我們的配置變化不需要伺服器過載、重啟或二進位制升級。所以它是非常高效和可擴充套件的。

OpenResty Edge 將配置同步到閘道器節點,無需過載、重啟或二進位制升級

用 curl 測試法語 Accept-Language 重定向

在終端上,我們可以用 curl 傳送 HTTP 請求。

curl -I -H 'Accept-Language: fr-CA, fr, en' http://test-edge.com/

這裡我們指定了 3 種語言:fr-CA, fr, 和 en 。所以對於這個請求,法語優先於英語。

用 Accept-Language: fr-CA, fr, en 傳送 curl 請求測試重定向

執行這個命令。

注意看這裡確實重定向到了 /fr/

響應顯示對法語 Accept-Language 頭重定向到 /fr/

我們可以讓 curl 命令自動跟隨重定向。

curl -L -H 'Accept-Language: fr, en' http://test-edge.com/

這裡使用 -L 選項。

用 curl -L 自動跟隨語言重定向

執行這個命令。

我們可以看到返回的法語文字。

跟隨重定向後返回的法語頁面內容

新增兜底頁面規則將其他語言重定向到英文

接下來,我們會新增一個通用的頁面規則以實現當客戶端傳送的請求頭帶有其他語言時重定向到英文頁面。

為英文兜底建立第二條頁面規則

建立一個新的頁面規則。

為兜底規則啟用 URI 條件

我們仍然啟用一個規則條件來檢查 URI /

為兜底條件選擇 URI 變數

兜底條件已選定 URI 變數

仍然選擇 URI

為兜底條件選擇字串等號運算子

仍然選擇字串等號。

準備為兜底條件輸入 URI 值

輸入 / 為兜底規則匹配根路徑

像以前一樣輸入值 /

兜底條件只匹配根 URI、不檢查語言

條件編寫完成。這一次我們不用再去檢查請求頭了。

像上次一樣新增一個新的重定向動作。

為兜底規則新增重定向動作

為兜底規則選擇重定向動作型別

配置兜底規則的重定向目標

為兜底重定向選擇自定義目標 URI,輸入 /en/

這一次,我們為目標 URI 輸入 /en/

為兜底規則啟用命中即跳過後續規則

如果命中此條規則的話跳過所有餘下的頁面規則。

讓兜底規則仍先於其他普通規則執行

我們仍然要確保這個規則在其他“普通規則”之前執行。

儲存英文兜底重定向規則

儲存這個規則。

兜底規則排在代理規則之前、法語規則之後

我們可以看到新新增的頁面規則在代理規則之前,但在上次新增的那條法語規則之後。

再次釋出新配置

再做一次新配置的釋出。

釋出更新後的配置

再次將配置釋出到所有閘道器叢集

再次釋出!

配置再次同步完成

同步又完成了。

在瀏覽器中測試英文兜底重定向

這次我們使用瀏覽器測試 / 路徑。我們的瀏覽器的語言設定是英文。

這裡可以看到返回的是英文文字 Hello, world。

瀏覽器顯示英文頁面,位址列 URL 改寫為 /en/

從位址列我們還可以看到,URI 變成了 /en/

常見問題

OpenResty Edge 如何判斷訪客的語言?

它讀取 Accept-Language 請求頭,也就是客戶端隨每個請求傳送的語言偏好。頁面規則用字首運算子加正則(如 fr\b)匹配這個頭,因此 frfr-CA 這類地區變體都會命中。任何設定了 Accept-Language 的客戶端——包括 curl——都會觸發同一條重定向。

不改 nginx.conf 也能根據瀏覽器語言重定向嗎?

可以。整條規則都在 OpenResty Edge 的 Admin 控制檯裡搭建:一個 URI 條件、一個 Accept-Language 請求頭條件,再加一個重定向動作。釋出一次配置後,規則就會下發到所有閘道器叢集,無需伺服器過載、重啟或二進位制升級。

如何設定預設語言兜底?

再加一條頁面規則,只匹配根路徑 /、不檢查 Accept-Language,動作是重定向到 /en/。把語言專屬規則排在它前面,讓兜底規則最後執行。本教程裡法語規則先匹配法語客戶端,其餘所有語言都落到英文頁面。

為甚麼把語言重定向標記為置頂規則?

置頂規則總是先於普通規則執行,因此語言重定向會在服務根路徑的反向代理規則之前被判定。配合“命中即跳過後續規則”,就能保證客戶端在任何其他規則響應之前,被送到正確的語言路徑。

客戶端一次傳送多種語言時會怎樣?

Accept-Language 頭可以列出多種語言,例如 fr-CA, fr, en。由於用的是字首匹配,只有第一個(優先順序最高的)語言會被考慮。在這個例子裡法語優先於英語,因此請求被重定向到 /fr/

關於 OpenResty Edge

OpenResty Edge 是一款專為微服務和分散式流量架構設計的全能型閘道器軟體,由我們自主研發。它集流量管理、私有 CDN 構建、API 閘道器、安全防護等功能於一體,幫助您輕鬆構建、管理和保護現代應用程式。OpenResty Edge 擁有業界領先的效能和可擴充套件性,能夠滿足高併發、高負載場景下的苛刻需求。它支援排程 K8s 等容器應用流量,並可管理海量域名,輕鬆滿足大型網站和複雜應用的需求。

如果你喜歡這個教程,請訂閱這個部落格網站和我們的 YouTube 頻道B 站頻道。謝謝!

關於作者

章亦春是開源 OpenResty® 專案創始人兼 OpenResty Inc. 公司 CEO 和創始人。

章亦春(Github ID: agentzh),生於中國江蘇,現定居美國灣區。他是中國早期開源技術和文化的倡導者和領軍人物,曾供職於多家國際知名的高科技企業,如 Cloudflare、雅虎、阿里巴巴, 是 “邊緣計算“、”動態追蹤 “和 “機器程式設計 “的先驅,擁有超過 22 年的程式設計及 16 年的開源經驗。作為擁有超過 4000 萬全球域名使用者的開源專案的領導者。他基於其 OpenResty® 開源專案打造的高科技企業 OpenResty Inc. 位於美國矽谷中心。其主打的兩個產品 OpenResty XRay(利用動態追蹤技術的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最適合微服務和分散式流量的全能型閘道器軟體),廣受全球眾多上市及大型企業青睞。在 OpenResty 以外,章亦春為多個開源專案貢獻了累計超過百萬行程式碼,其中包括,Linux 核心、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,並編寫過 60 多個開源軟體庫。

關注我們

如果您喜歡本文,歡迎關注我們 OpenResty Inc. 公司的部落格網站 。也歡迎掃碼關注我們的微信公眾號:

我們的微信公眾號

翻譯

我們提供了英文版原文和中譯版(本文) 。我們也歡迎讀者提供其他語言的翻譯版本,只要是全文翻譯不帶省略,我們都將會考慮採用,非常感謝!