一個當之無愧的 htaccess 轉 nginx 轉換替代方案,必須承認兩種網頁伺服器採用不同的處理模型,並拒絕為某些條件、未知的旗標,或僅限 Apache 的構造虛構等價的 Nginx 指令。通用的轉換工具往往會將 .htaccess 上傳到遠端服務,或是輸出一段看似完整的 nginx.conf 區塊,卻仍潛藏 Apache 的假設:路徑前綴剝除、RewriteCond 變數評估、查詢字串處理,以及在集中式設定中根本不存在的每目錄 AllowOverride 範疇。Apache 手冊在 mod_rewrite 介紹中已清楚說明其每目錄模型,而 Nginx 的 rewrite 模組文件則記載了在任何 rewrite 執行前就已決定的伺服器與 location 評估順序;將兩份文件並排閱讀,便能理解為何一對一的對應不可能存在。一個較安全的替代方案會把轉換範圍縮窄、在本機處理貼上的片段,並針對任何超出文件支援範圍的部分,回傳明確附帶行號的人工審核警告。這正是 htaccess to Nginx Converter 所要扮演的角色:在任何重新載入之前,提供一份讓工程師重新掌握主導權的初稿盤點,這對想要得到一個可重現的真實遷移起點,而非一份看似合理卻無人能稽核的設定檔的人特別有幫助。來源片段本身的擷取則由另一個獨立步驟負責,說明如何在伺服器未公開的情況下,從網站取得 .htaccess 檔案。

一個替代轉換工具究竟應該承諾什麼
多數搜尋「htaccess to nginx converter」的結果都承諾一鍵產生完整的 nginx.conf 檔案。這個承諾,正是一個真正的替代方案必須打破的部分。Apache 在請求階段透過目錄樹讀取 .htaccess、遵守 AllowOverride,並在每請求管線中評估 RewriteCond。Nginx 則是在 rewrite 處理開始之前,就已在 server 與 location 情境中讀取集中式設定,這一點可參考官方的 rewrite 模組文件。這兩種處理模型是有意設計成不同的,因此值得挑選的替代方案應該明確指出這個差距,而不是加以粉飾。
一個值得信賴的替代方案會把遷移工作視為工程任務,而非單純的文字替換。它僅在文件支援的子集內進行轉換、在本機執行使 .htaccess 絕不離開工作站,並標示每一行無法翻譯的部分。任何會產出語法正確但語意錯誤規則的工具——例如猜測式的 RewriteCond 展開,或是靜默地略過旗標——都會讓正式環境的重新載入陷入連任何測試套件都無法察覺的危險。替代方案的角色,是在交還乾淨的初稿之餘附上明確的待辦清單,而不是一份日後再也無人能稽核的完整設定。
讓誠實轉換成為可能的狹窄契約
這份轉換契約刻意維持精簡。剖析器一次處理一行受限的內容,略過 RewriteEngine On,保留註解,並將 RewriteRule 的旗標集合限制為 L、R、R=301 以及 R=302。一個 Apache 的永久重新導向會對應成 Nginx 的 permanent 旗標,暫時重新導向會對應成 redirect,而內部的 last 規則則對應成 last。超出此集合的旗標——包括 QSA、END、F、G、B 以及 NC——會停止該規則的轉換,並改為回報警告而非猜測輸出,因為其語意仰賴 Nginx 並未具備的 Apache 功能。rewrite 相關的詳細背景可參考Apache mod_rewrite 介紹,這是在必須手動解決警告時最正確的參考資料。
位於文件根目錄的 .htaccess 中的模式通常會在目錄前綴被移除後進行比對,因此它們常以插入符開頭但沒有前置斜線。Nginx 的 rewrite 模式看到的是以斜線開頭的 URI,因此轉換器會為支援的根目錄情境模式補上這個前置斜線。這是一項已在文件中載明的範疇假設,並非通用於巢狀 .htaccess、Alias 對應或 location 專屬 Nginx 區塊的轉換;當任何規則落入該範疇之外時,警告清單便會明確告知。
| Apache 來源 | Nginx 輸出 | 工具行為 |
|---|---|---|
| RewriteRule pattern sub [L,R=301] | rewrite ^/pattern sub permanent; | 為根目錄情境模式補上前置斜線後進行翻譯 |
| RewriteRule pattern sub [L,R] | rewrite ^/pattern sub redirect; | 翻譯為暫時重新導向 |
| RewriteRule pattern sub [L] | rewrite ^/pattern sub last; | 翻譯為內部 last rewrite |
| Options -Indexes | autoindex off; | 以非 rewrite 對應方式翻譯 |
| ErrorDocument 404 /path | error_page 404 /path; | 僅對本地檔案進行翻譯;外部 URL 會發出警告 |
| Header set X-Robots-Tag "value" | add_header X-Robots-Tag "value"; | 僅翻譯單一帶引號的值 |
| RewriteCond ... (任意) | — | 回報警告,不輸出 rewrite |
| RewriteRule ... [QSA|END|F|G|B|NC] | — | 回報警告,該規則予以抑制 |
| 單破折號目標 (-) | — | 回報警告,不靜默替換為 Nginx 對應內容 |
RewriteCond 行永遠不會被自動翻譯。Apache 條件可檢查 HTTPS 狀態、主機名稱、檔案、目錄、查詢字串、標頭與擷取群組,且其評估順序與伺服器架構至關重要。當 RewriteRule 跟在某個條件之後時,工具會連同該規則一併抑制,而不是輸出一條可能改變流量、造成迴圈或暴露路由的非條件式重新導向。以單破折號表示、不進行替代的 Apache 目標基於相同理由也會被保留不翻譯;它常與會改變存取或處理行為而不變更 URI 的旗標併用,因此一個字面上的破折號並非安全的 Nginx 對應方式。警告本身就是結果的一部分。
如何使用 htaccess to Nginx Converter 轉換一個聚焦的片段
- 將一小段文件根目錄的 .htaccess 片段貼入htaccess to Nginx Converter,讓它僅掃描支援的指令子集。請讓片段聚焦於您真正打算遷移的規則,理想上是位於網站根目錄的 rewrite,而非東拼西湊自各子目錄的集合。
- 開啟輸出結果並逐行閱讀。針對每一條 RewriteRule,請確認已補上前置斜線(因為 Apache 根目錄情境模式不以斜線開頭,而 Nginx URI 模式則會),並依文件所載的對應表檢查旗標翻譯:[L,R=301] 會變成 rewrite ... permanent;,[L,R] 會變成 rewrite ... redirect;,[L] 會變成 rewrite ... last;。針對每一個引用行號的警告,請回到原始的 Apache 該行,並對照 mod_rewrite 介紹與 Nginx rewrite 模組參考資料進行確認,再將該規則視為已完成遷移。
- 將審核過的片段放入正確的 Nginx 情境中,備份現行的設定檔,執行 nginx -t 來驗證組合後的結果,並針對任何使用 [R] 旗標的路徑——包括查詢字串、替代主機標頭與 HTTPS 升級——準備具代表性的測試請求。在重新載入之前,請檢查 Location 回應標頭,而非單獨依賴瀏覽器網址列。
轉換器絕不隱藏的警告類別
轉換器會依一組小而可預測的分類回傳警告,而行號能讓您直接跳回來源對應位置。RewriteCond 行必定會產生警告,因為其變數與評估順序並不安全到可以直接翻譯。未知的 RewriteRule 旗標會產生警告並抑制該規則。單破折號的 Apache 目標會發出警告,因為它通常帶有 Nginx 並無對應的旗標驅動語意。看起來像是 Alias 對應、location 區塊的重新導向,或位於 <Directory>、<Files> 或 <LocationMatch> 容器內的任何規則,都會發出警告——因為轉換器僅處理文件根目錄的 .htaccess 片段,直接重寫這類規則將會改變其原本的意義。
外部的錯誤文件與條件式標頭同樣會發出警告。工具可處理本地端的 ErrorDocument 404 /path 以及帶引號的 Header set X-Robots-Tag "value";任何其他狀態碼、絕對 URL 目標、合併式的 Header 指令、環境變數,或任何指令容器,皆須手動遷移。將警告清單視為遷移檢查清單(而非一份可忽略的邊緣案例清單),正是順利切換與漫長維護停機之間的差別所在。
將片段放入真正的 nginx.conf 中
輸出的內容僅是一個片段,而非完整的設定。它不會建立 http、server 或 location 區塊、不會選擇 listen 連接埠、不會設定 server_name、不會設定 TLS、不會指定文件根目錄、不會保留 PHP 路由、不會設定代理轉送,也不會定義日誌。每一行經審核的內容都必須根據 Nginx 核心 error_page 文件與 rewrite 模組參考資料,並對照實際的應用程式架構,置入正確的情境中。一條 rewrite ... last; 規則通常應放在 location / 區塊內;一條 autoindex off; 屬於 server 或 http 層級指令;而 error_page 404 ...; 必須放在 Nginx 確實能服務您所寫路徑之處,這可能需要獨立的 location 區塊。
轉換器並不會執行 nginx -t、不會檢查已安裝的模組、不會探索 include 順序,也無法存取您的伺服器。一行規則可能在語法上有效,卻對其所在情境而言是錯誤的。因此,備份現行設定、保持可還原的工作階段、驗證整份組合後的檔案,以及在重新載入前準備具代表性的測試請求——這份紀律屬於工程師的責任,而非工具的責任。永久重新導向需要格外留心,因為瀏覽器與中介節點可能會加以快取;建議先在受控環境中使用暫時重新導向進行測試,待驗證完舊路徑、新路徑、查詢字串、替代主機與 HTTPS 行為後,再切換為永久重新導向,才能避免那種往往得花上數週才能挽回的無聲回歸。
這個替代方案的適用與不適用情境
這套轉換器能妥善處理一種類型的工作:將一小段文件根目錄的 .htaccess 轉換成一份 nginx.conf 的起始片段,並由工程師親自處理所有複雜的部分。當來源包含身分驗證、授權、防盜連、代理邏輯、CMS front-controller 規則,或任何堆疊式的條件時,它就比較不適合,此時手動改寫反而更合適。在這些情況下,遷移屬於工程工作而非大量文字替換,警告清單會比已轉換清單更長,而這本身就是一個有用的訊號:當轉換器承認某條規則需要人工處理時,它才是誠實的。作為一份盤點助手使用時,它能提供可靠的初稿,以及一份清楚列出仍須手動建立項目的紀錄——這正是一個值得挑選的替代方案所應該交付的成果。
若您正在權衡各種選項,A Keyword Density Checker Alternative for Local Drafts 對此有詳細說明。