快訊
2026-08-15
Wordpress主機

.htaccess 常用規則:轉址、防盜連、壓縮的官方寫法

約 19 分鐘閱讀
廣告

⚡ 站長快讀:核心重點

  • 文章屬性:教學實戰(Apache 伺服器設定)
  • 適用系統:Apache HTTP Server 2.4(mod_brotli 需 2.4.26 以上)
  • 難易度 / 耗時:⭐⭐⭐ / 約 20 分鐘
  • 核心結論:.htaccess 常用規則就是轉址、防盜連、壓縮三類,但 Apache 官方的寫法跟中文圈流傳的抄法差很多——能用 Redirect 就別動 RewriteRule,防盜連官方也早就不建議只靠擋 Referer。
  • 適用對象:用共享主機、cPanel 跑 WordPress 或靜態網站,拿不到 httpd.conf 權限的站長

📌 快速答案

一句話答案:.htaccess 常用規則分三類——轉址優先用 Redirect、有條件判斷才用 RewriteRule;防盜連用 SetEnvIf 搭配 Require env;壓縮則靠 mod_deflate 或 mod_brotli 掛上 AddOutputFilterByType。


🧰 開始前的準備

  • 系統需求:Apache HTTP Server 2.4.x。主機必須已開啟 AllowOverride——官方預設值是 None,代表 .htaccess 會被完全忽略
  • 權限需求:能寫入網站根目錄的 FTP / SFTP 或主機面板檔案管理員即可,不需要 root
  • 需要工具:純文字編輯器、能看 HTTP 標頭的工具(瀏覽器開發者工具或 curl)、能讀 Apache error log 的管道(cPanel 多半有「錯誤記錄」頁)
  • 預計耗時:約 20 分鐘
  • 難度門檻:看得懂基本正規表示式會輕鬆很多,但本文每條規則都逐項拆給你看

🔍 為什麼你需要這個?

先講結論:網路上絕大多數的 .htaccess 懶人包,都在教你用 RewriteRule 解決根本不需要 RewriteRule 的問題(這是站長我自己的觀察,不是統計數字)。而「不該用 RewriteRule」這件事,Apache 官方文件自己講得比誰都直白。

站長我整理這篇的動機,是中文圈的 .htaccess 文章長年在互抄同一份十幾年前的規則清單,卻漏掉官方文件裡三個關鍵前提,而這三點正是你複製貼上後「規則沒生效」或「整站白畫面」的真正原因:

1. 官方說:能用主設定檔就別用 .htaccess。 Apache 文件〈.htaccess files〉明講,只要你拿得到主伺服器設定檔,所有設定都該寫在那裡,包含 mod_rewrite 規則。.htaccess 最主要的正當理由,就是你在共享主機、拿不到 root(官方另外還列了 CMS 隨套件附帶 .htaccess、管理員不願頻繁改設定等情境)。

2. 官方說:mod_rewrite 是最後手段(last resort)。 〈When not to use mod_rewrite〉整份文件都在講「這件事別用 RewriteRule 做」。轉址該用 Redirect、路由該用 FallbackResource、擋 IP 該用 Require not ip

3. 官方說:防盜連的建議做法不是 mod_rewrite。 那份教你用 RewriteCond %{HTTP_REFERER} 的舊官方文件〈Using mod_rewrite to control access〉整份已被標為 deprecated、內容併進〈When not to use mod_rewrite〉,而官方在新文件裡把首選換成了 SetEnvIf 搭配 Require env(規則本身沒有被廢,是那份文件被廢)。

換句話說,你要的不是「更多規則」,而是「知道哪一條不該寫」。以下三類規則,我一律先給官方首選寫法,再給 .htaccess 情境下的替代寫法,並標明代價。

廣告
.htaccess 轉址防盜連壓縮:Apache 官方首選做法與 .htaccess 替代寫法對照表

🛠️ 實戰步驟

⚠️ 動手前務必看這段:.htaccess 是即時生效的——存檔的下一個 request 就套用,沒有重啟緩衝、沒有預演。一個語法錯字就會讓整站噴 HTTP 500,而且是整個目錄與所有子目錄一起噴。

停止條件(符合任一,先別動):①手上沒有現存 .htaccess 的備份 ②沒有第二條進主機的管道(FTP 之外還有面板或 SSH),萬一 500 連後台都進不去 ③不確定主機是 Apache(Nginx 完全不吃 .htaccess;OpenLiteSpeed 只吃其中的 mod_rewrite 規則,LiteSpeed Enterprise 相容度高但仍非 100%) ④這是正在營運、有金流的站,而你沒有測試環境。

一定要做的第一件事:把現有的 .htaccess 下載一份存成 htaccess-backup-20260715.txt 放桌面。WordPress 站的根目錄 .htaccess 內含固定網址的重寫規則,砍掉會讓全站文章連結 404。

步驟一:先確認主機到底理不理你

這一步能省下你大把除錯時間:規則沒生效,官方點名「最常見的原因」不是規則寫錯,是 AllowOverride 沒設對。官方文件的 Troubleshooting 段落給了一招很賊的測法——故意寫一個不存在的指令進去。

在 .htaccess 裡放這一行,然後重新整理網頁:

TestMe

判讀方式如下(先講清楚:官方用的字是「幾乎可以確定」,不是百分之百,但實務上這招準度很高):

  • 網頁噴 HTTP 500 → 恭喜,.htaccess 有被讀取,AllowOverride 有開。把 TestMe 刪掉繼續。
  • 網頁正常顯示 → 官方原話是「你幾乎可以確定 AllowOverride None 正在生效」,也就是 .htaccess 沒被讀。這時候寫再多規則都是白工,得去主機面板找「.htaccess 支援」開關,或直接開單問主機商。

如果是噴 500,順手去看 error log,官方文件示範的錯誤長這樣:

[core:alert] [pid 12345] [client 192.168.1.50:54321]
/var/www/html/.htaccess: DirectoryIndex not allowed here

這行 not allowed here 官方明講有兩種可能,得自己查該指令的文件才知道是哪一種:要嘛這個指令在 .htaccess 裡根本永遠不被允許,要嘛是你的 AllowOverride 等級不夠。Apache 把可覆寫的指令分成 AuthConfigFileInfoOptionsLimit 等類別,每個指令的官方文件都有一行 Override 標明它需要哪一類——查那一行就能分辨是哪種狀況。想查 403、500 這些狀態碼各自代表什麼,可以參考站內的〈HTTP 狀態碼是什麼?404、403、500 意思與 404 由來一次搞懂〉。

💡 給有主機權限的人:官方提供了 AllowOverrideList,可以只放行指定的幾個指令,比整類開放安全得多(很舊的 2.4.x 小版本可能還沒有,用之前先確認你的版本):

“`apache

AllowOverride None

AllowOverrideList Redirect RedirectMatch RewriteEngine RewriteRule RewriteCond

“`

沒列到的指令一旦出現在 .htaccess 就會直接噴錯。這是「全開」與「全關」之間很實用的中間地帶。

步驟二:轉址規則——先問「這條真的需要 RewriteRule 嗎?」

直接結論:單純的「A 換成 B」轉址,一律用 RedirectRedirectMatch,不要用 RewriteRule。 官方〈When not to use mod_rewrite〉寫著,這類轉址「該用這些指令完成,而不是 RewriteRule」;而在〈Redirecting and Remapping〉裡,官方對「資源搬到另一台伺服器」的建議也給了理由——RedirectRedirectMatch 更簡單、更有效率

廣告

2-1 基本轉址:Redirect 會自動帶路徑

Redirect "/one/" "http://one.example.com/"

這裡有個很多人不知道的官方行為:Redirect 會保留路徑資訊。也就是說,上面這一條不只轉 /one/,連 /one/two.html/one/three/four.html 都會一起轉到對應位置。你不需要為每篇文章寫一條。

要用正規表示式就換 RedirectMatch:

RedirectMatch "^/(puppies|canines)/(.*)" "/dogs/$2"

2-2 強制 HTTPS:官方首選其實不在 .htaccess

官方對「全站導 HTTPS」的首選解法,是在專屬的 80 埠虛擬主機裡放一條 Redirect permanent:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect permanent "/" "https://www.example.com/"
</VirtualHost>

但這需要主設定檔權限。官方接著明講:如果你只有 .htaccess 可用,mod_rewrite 才是這個情境的正確工具——這是官方少數點名「該用 RewriteRule」的場合:

廣告
RewriteEngine On
RewriteCond "%{HTTPS}" !=on
RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L]

逐項拆解:

  • %{HTTPS}:連線走 SSL/TLS 時值為 on,否則為空或 off
  • [R=301]:發出永久轉址,官方說明這會告訴搜尋引擎更新索引(暫時性搬移才用 R=302)
  • [L]:本條命中就停止後續規則比對

⚠️ 踩雷預告——套 Cloudflare 或負載平衡的人請看:官方特別警告,%{HTTPS} 不是一般的環境變數,它是直接去問 mod_ssl 的。如果 TLS 是在上游的負載平衡器或反向代理就終止掉,mod_ssl 根本沒經手這條連線,%{HTTPS}永遠回報 off——即使使用者明明是用 HTTPS 連進來的。結果就是無限轉址迴圈。這種情境要改看上游代理設的標頭:

“`apache

RewriteEngine On

RewriteCond “%{HTTP:X-Forwarded-Proto}” =http [NC]

RewriteRule “^(.*)” “https://%{SERVER_NAME}$1” [R=301,L]

“`

但官方同時提醒:X-Forwarded-Proto 是可以被偽造的。攻擊者只要繞過代理直連你的後端就能亂送這個標頭。所以這招的前提是——你控制得了上游代理、而且它會在每個 request 覆寫該標頭。

2-3 別把 Let’s Encrypt 鎖在門外

強制 HTTPS 之後最常見的災情:憑證到期時 certbot 續簽失敗。因為 ACME 驗證需要用純 HTTP 存取 /.well-known/acme-challenge/,而你剛剛把所有 HTTP 都轉走了。官方給的解法是在轉址規則之前插一條例外:

RewriteEngine On
RewriteRule "^/\.well-known/acme-challenge/" - [L]
RewriteCond "%{HTTPS}" !=on
RewriteRule "^(.*)" "https://%{SERVER_NAME}$1" [R=301,L]

那個 -(破折號)是官方定義的「不要重寫」替換值,搭配 [L] 就等於「這個路徑放行,別再往下比對」。

⚠️ 照抄前先看這個:上面是官方原文照錄,但官方並沒有標明這個範例適用哪一種 context(同一頁其他範例有特別註明「僅適用目錄層級」,這條沒有)——請注意 ^/\.well-known/ 開頭那個斜線。而官方在〈.htaccess files〉裡明載:放進網站文件目錄的 .htaccess 時,前導斜線會被拿掉(詳見本文〈底層機制〉成本四)。兩邊對起來的結論是:這條直接照抄進根目錄 .htaccess 不會命中,比對式要改成 ^\.well-known/acme-challenge/,否則你的憑證照樣續簽失敗。

2-4 www 正規化

統一 example.comwww.example.com,官方最推薦的仍是虛擬主機裡的 Redirect;只有 .htaccess 可用時,才用這組(注意 NE 旗標):

RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteRule "^/?(.*)" "http://www.%{HTTP_HOST}/$1" [L,R,NE]

[NE] = No Escape。官方文件在〈Redirecting Anchors〉解釋:mod_rewrite 預設會把 # 之類的特殊字元做 URL 編碼(# 變成 %23),而這會直接打斷帶錨點的轉址。加上 NE 才不會被轉義。

2-5 最陰的陷阱:在 .htaccess 裡,誰先跑?

這點沒幾篇中文文章提過,但它會讓你的規則詭異地互相打架。官方〈Processing order〉寫得很清楚:

情境誰先執行
主設定檔 / 虛擬主機 contextmod_rewrite 先跑
目錄層級 context(也就是 .htaccess)mod_alias 先跑

也就是說,同一個檔案裡混用 RedirectRewriteRule 時,在 .htaccess 裡是 Redirect 先動手——跟你從上往下讀的直覺剛好相反。所以同一個路徑千萬別兩邊都寫。

步驟三:防盜連——官方推薦的寫法已經換人了

直接結論:官方現在的首選是 SetEnvIf 搭配 Require env,不是 mod_rewrite。 你在中文圈看到的那組 RewriteCond %{HTTP_REFERER},出自官方舊版〈Using mod_rewrite to control access〉,而那份文件已被官方標記為 deprecated、內容整併進〈When not to use mod_rewrite〉,並預告未來版本會移除

盜連(hotlinking)是指別的網站直接用你的圖片網址嵌在他們頁面上,用你的頻寬幫他們出圖。官方首選寫法:

SetEnvIf Referer example\.com localreferer
<FilesMatch "\.(jpg|png|gif)$">
    Require env localreferer
</FilesMatch>

只有在你需要更複雜的邏輯時——例如「不要擋掉,改回傳一張別的圖」——官方才說你可能需要 mod_rewrite:

RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
RewriteRule "\.(gif|jpg|png)$" "/images/go-away.png" [R,NC]

想直接擋掉就把替換值換成 -、旗標換成 [F,NC](F = Forbidden,回 403)。

兩個官方明講、但懶人包從來不提的前提:

1. HTTP_REFERER 是選用標頭,而且可以被偽造。 官方原話是這個標頭 “is optional and can be spoofed”。所以防盜連擋得住順手嵌圖的人,擋不住存心的人。別把它當資安機制看。

2. !^$ 那一行不是裝飾,是保命的。 它的作用是「Referer 為空時放行」。官方解釋得很明白:允許沒有 Referer 標頭的請求通過,是為了不要誤擋那些直接把網址貼到網址列的使用者,以及瀏覽器隱私設定會抑制 Referer 的人。少了這行,你會擋掉一票真人。

💡 順帶一提:同一份官方文件也把「擋惡意爬蟲」的建議從 mod_rewrite 換成了 SetEnvIfNoCase User-Agent + Require not env,並附上一句很誠實的評語——任何靠 User-Agent 字串的手法都能被「輕易規避」(trivially circumvented),因為那個字串是客戶端說了算。真的被打,官方要你去防火牆那層擋。

步驟四:壓縮——gzip 與 Brotli 的官方寫法

直接結論:壓縮就一行 AddOutputFilterByType,但要壓對型別、而且別碰圖片。

4-1 gzip(mod_deflate)

官方的 Sample Configuration 就是這一行:

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript

這裡有個名字造成的長年誤會值得講清楚:模組叫 mod_deflate、過濾器叫 DEFLATE,但它實際輸出的編碼是 gzip。官方原話是——為了確保與舊瀏覽器的完整相容性,gzip唯一支援的編碼,deflate 編碼並不支援。所以「要不要另外開 deflate?」這個問題本身就不成立。

要調壓縮強度用這個(數值 1 到 9,越高越省頻寬、越吃 CPU):

DeflateCompressionLevel 6

4-2 Brotli(mod_brotli,需 2.4.26 以上)

AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript

BrotliCompressionQuality 官方預設值是 5(可設 0–11),官方對兩個極端的註解很有參考價值:

品質值官方註解
4大致等同 gzip level 6
5預設值,動態內容的合理平衡點
11壓縮率最好但非常慢,只適合搭配快取

換句話說,把 Brotli 開到 11 去壓動態 HTML,是拿 CPU 換頻寬的賠本生意。

4-3 三個一定要知道的官方警告

1. BREACH:壓縮 + TLS 有資訊洩漏風險。 mod_deflate 與 mod_brotli 的官方文件都在最顯眼處放了同一段警告——某些網頁應用在 TLS 連線承載壓縮資料時,會受到 BREACH 家族攻擊的資訊洩漏影響。這不代表你不該開壓縮(現代網站幾乎都開),但含機敏資料的動態回應要另外評估。

2. 別壓圖片。 JPEG、PNG、GIF 本身已經壓過,再壓一次只是白燒 CPU、體積還可能變大。官方範例是這樣排除的:

   SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png)$" no-gzip

3. Vary: Accept-Encoding 不用你手動加。 官方明說 mod_deflate 與 mod_brotli 會自動送出這個標頭,用途是提醒中間的 proxy:快取的壓縮版本只能送給有宣告 Accept-Encoding 的客戶端。如果你的壓縮條件牽涉到 User-Agent 之類的其他標頭,就得自己補:

   Header append Vary User-Agent

步驟五:驗證結果

三項都用同一支工具驗:curl,搭配 -sI 這組參數(-s 安靜模式、-I 只要回應標頭)。

轉址:用 curl -sI 對你的舊網址發一個 HEAD 請求,看回應碼與 Location。不要只用瀏覽器測——瀏覽器會把 301 快取起來,你改完規則後看到的很可能是舊的快取結果。判讀:第一行要是 HTTP/1.1 301 Moved Permanently,而 Location: 要指到正確的新網址。

壓縮:同樣用 curl -sI,額外加一個 -H 參數送出編碼宣告標頭 Accept-Encoding: gzip, br,目標指向你的首頁。判讀:回應標頭裡要出現 Content-Encoding: brContent-Encoding: gzip,並且要有 Vary: Accept-Encoding,兩者都在才算成功。

防盜連:同樣用 curl -sI,加上 -e 參數偽造一個「外站來源」當 Referer,目標指向你站上任何一張圖片。判讀:預期拿到 403;如果拿到 200,代表規則沒生效——回步驟一確認 AllowOverride,或檢查 FilesMatch 的副檔名有沒有涵蓋到那張圖。

💡 為什麼指令不直接寫成可複製的整行? 本站的邊緣防火牆會把「curl + 網址」的組合判成攻擊字串而擋下發文(這是誤判,但擋在站台之外、我改不動),所以這裡改用敘述式寫法。參數本身照抄即可,網址換成你自己的。


🔬 底層機制:.htaccess 的成本,到底付在哪一層?

理解這段,你才會懂官方為什麼一直勸退。.htaccess 的方便是有代價的,而代價是每一個 request 都在付

.htaccess 的四筆固定成本:每目錄尋找、上層逐級掃、每次請求重讀、regex 每次重編譯

成本一:開了就要付,不管你用不用。 官方講得非常直白——只要 AllowOverride 設成允許使用 .htaccess,httpd 就會在每一個目錄裡尋找 .htaccess 檔案,「無論你實際上到底有沒有用它」。這是啟用即產生的固定開銷。

成本二:要往上層逐級掃。 Apache 必須把所有上層目錄的 .htaccess 湊起來,才能得到完整的指令集。官方舉的例子是,請求 /www/htdocs/example 底下的檔案時,httpd 得去找:

/.htaccess
/www/.htaccess
/www/htdocs/.htaccess
/www/htdocs/example/.htaccess

這四次檔案系統存取,即使四個檔案一個都不存在,也照樣要跑。 但官方在後面補了一個誠實的但書:要湊滿這四次,前提是連根目錄 / 都開啟了 .htaccess——而那並不是常見的設定。所以實際次數通常少於四次,重點是「次數隨目錄深度增加,且找不到也要付」。

成本三:每次請求重讀、正規表示式每次重編譯。 主設定檔的指令是伺服器啟動時載入一次;.htaccess 則是每次有文件被請求時就重新載入一次。官方在 mod_rewrite 的說明裡補了更刺的一刀:在 .htaccess 情境下,正規表示式是每個 request 都重新編譯,而在主設定檔裡只編譯一次、之後快取。

這也解釋了官方那句「mod_rewrite 在主設定檔 context 運作得更好」不是玄學,是實打實的執行成本差異。

成本四(也是最容易翻車的):前導斜線會被拿掉。 這是「照抄 httpd.conf 的規則到 .htaccess 就壞掉」的頭號原因。官方的對照表非常清楚:

# 寫在 httpd.conf
RewriteRule "^/images/(.+)\.jpg" "/images/$1.png"

# 寫在網站根目錄的 .htaccess
RewriteRule "^images/(.+)\.jpg" "images/$1.png"

# 寫在 images/ 目錄的 .htaccess
RewriteRule "^(.+)\.jpg" "$1.png"

規則在目錄層級 context 下,是相對於當前目錄,而不是原始請求的 URI。根目錄的 .htaccess 會被拿掉開頭那個 /;放在 images/ 裡的話,連 /images/ 整段都會被拿掉。你的正規表示式必須跟著省掉那一截——這也是為什麼很多人的規則「在網路上看到明明是對的,貼過來就是不動」。


🔙 萬一翻車:回退步驟

情境一:整站噴 HTTP 500

這是 .htaccess 語法錯誤的標準症狀,而且會連後台一起帶走。

1. 用 FTP / 主機面板把 .htaccess 改名htaccess.bak(不要直接刪,你還要看它)。改名的瞬間站就會活回來——因為 Apache 找不到它就當沒這回事。

2. 站活了之後,去看 error log。官方說錯誤訊息會直接告訴你是哪一行、哪個指令出事,例如 RewriteCond: bad flag delimiters

3. 把備份檔的規則一次貼回一條,每貼一條就重新整理一次網頁。錯的那條一貼就會 500,當場抓到。

情境二:規則貼了,但完全沒反應

官方點名的「最常見原因」就是 AllowOverride 沒設對,而不是你規則寫錯。 回步驟一跑一次 TestMe 測試:沒噴 500 就是主機沒開,寫再多都沒用,去找主機商。

情境三:無限轉址迴圈(ERR_TOO_MANY_REDIRECTS)

最常見的成因是強制 HTTPS 規則遇上上游 TLS 終止。 對照步驟 2-2 的官方警告:如果站在 Cloudflare、負載平衡器或反向代理後面,%{HTTPS} 會永遠回報 off,於是「已經是 HTTPS 了還是被轉去 HTTPS」無限循環。

急救:先把那段 HTTPS 規則整段註解掉(每行前面加 #)讓站活過來,再改用 %{HTTP:X-Forwarded-Proto} 的版本。

情境四:WordPress 全站文章 404,只剩首頁

你多半是把 WordPress 那段固定網址規則洗掉了。 WordPress 根目錄 .htaccess 裡 # BEGIN WordPress# END WordPress 之間那段是它自己維護的,不要手動編輯,自訂規則請寫在那對標記之外。救法:進 WordPress 後台 設定 → 固定網址,什麼都不用改,直接按「儲存設定」,WordPress 會自己把那段規則重新寫回去。


💡 總結:進階玩法與底層邏輯

站長我把官方那幾份文件從頭讀完之後,最大的體會是:.htaccess 的規則清單不難,難的是知道每條規則「該不該存在」。 官方文件裡的態度一致到近乎嘮叨——mod_rewrite 是最後手段、.htaccess 是次選、能上主設定檔就上去。這跟中文圈「來,這 20 條規則複製貼上」的教學氣質完全相反,而官方那套才是對的:每多一條 RewriteRule,你就多付一份每個 request 都要重編譯的正規表示式成本,還多一個未來會忘記自己為什麼寫它的維護債。

三個可以驗證的具體錨點,幫你判斷手上的文章是不是過期貨:

  • mod_brotli 從 Apache 2.4.26 才有,BrotliCompressionQuality 預設 5。主機版本低於 2.4.26 就別找了。
  • 舊版〈Using mod_rewrite to control access〉已被官方標為 deprecated 並預告移除,還在用它教防盜連的文章,基本上是十年前的存貨。
  • mod_deflate 只吐 gzip、不支援 deflate 編碼——這是官方為了相容舊瀏覽器的明確設計,不是 bug。

進階一點的玩法:如果你的 CSS / JS 是建置流程產出的,可以走官方的「預壓縮內容」方案——事先產好 .css.br / .js.br,再用 RewriteCond 檢查客戶端是否接受 br 並直接送檔,同時用 E=no-brotli:1,E=no-gzip:1 避免二次壓縮。這樣就不必每個 request 重壓一次。細節在 mod_brotli 官方文件的 Serving pre-compressed content 段。

想在本機安全地試這些規則、而不是拿正式站當白老鼠,可以用 XAMPP 架一套本機環境練手,見〈在自己的電腦用 XAMPP 架設 WordPress 網站(Windows 篇)〉。

🔬 證據等級說明:本文所有規則、預設值與行為描述,皆取自 Apache HTTP Server 2.4 官方文件(2026-07-15 查證),屬官方事實交叉查證,非站長實機實測數據。你的主機商可能套用了不同的模組組合或 AllowOverride 政策,套用前請以步驟一實測為準。


❓ 常見問題

Q:我的 .htaccess 規則完全沒作用,是不是寫錯了?

先別改規則。照步驟一丟一行 TestMe 進去重新整理:沒有噴 HTTP 500,就代表 .htaccess 根本沒被讀取,AllowOverride None 正在生效,你改到天亮都不會有反應。這時候要做的是去主機面板找 .htaccess 支援開關,或開單問主機商。有噴 500 才是規則本身的問題,去 error log 看它指哪一行。

Q:轉址到底該用 Redirect 還是 RewriteRule?

單純的「這個網址換到那個網址」——包含整個目錄搬家——用 Redirect;需要正規表示式比對用 RedirectMatch;只有在需要條件判斷(檢查 Referer、HTTPS 狀態、檔案存不存在)時才用 RewriteRule。官方的原則是 mod_rewrite 是最後手段。額外提醒:Redirect 會自動保留下層路徑,不必為每個子頁面各寫一條。

Q:Nginx 主機可以用 .htaccess 嗎?

不行,而且 LiteSpeed 那邊要分兩種講,別混為一談:

  • Nginx:完全不讀 .htaccess,放了就是死檔。
  • OpenLiteSpeed(免費版):依官方文件,只支援 .htaccess 裡的 mod_rewrite 規則、不支援 Apache 指令,而且要先在 WebAdmin 開啟「Auto Load from .htaccess」、改動後還需要重啟才會載入;不支援的指令會被靜默忽略(不噴錯、就是沒作用)。也就是說,本文步驟三的 SetEnvIf + Require env 防盜連、步驟四的 AddOutputFilterByType 壓縮,在 OLS 上都不會生效,得改用它自己的設定介面。
  • LiteSpeed Enterprise(商業版):官方自稱支援 Apache 的 rewrite 規則與大多數 Apache 指令,且會自動偵測 .htaccess 變動、免重啟。相容度高,但「大多數」不等於全部,照抄前仍請以步驟五實測驗證。

不確定自己主機跑什麼,curl -sI 看回應標頭的 Server: 欄位最快。

Q:防盜連擋得住嗎?

擋得住順手嵌圖的,擋不住存心的。官方文件自己就寫明 HTTP_REFERER 這個標頭是選用的、而且可以被偽造(spoofed),攻擊者送個假 Referer 就過了。它的定位是「降低頻寬被無意佔用」,不是資安機制。真的要保護內容,得走簽章網址或 CDN 的 token 驗證那條路。

Q:gzip 跟 Brotli 要開哪個?兩個都開會衝突嗎?

老實說:官方文件並沒有直接說明兩個模組同時掛載時的挑選行為,這點本文不替官方發明答案。可以確定的是客戶端會用 Accept-Encoding 宣告自己支援哪些編碼,而官方明確講過的是——若你自行提供預壓縮檔,要用 E=no-brotli:1,E=no-gzip:1 防止二次壓縮。Brotli 壓縮率較好,但官方標註 BrotliCompressionQuality 4 才「大致等同 gzip level 6」,預設 5 是動態內容的平衡點。別把它調到 11 去壓動態頁——官方直說那很慢,只適合搭配快取。

Q:這些規則在舊版 Apache 也適用嗎?

轉址與防盜連的規則在 Apache 2.4 全系列通用。壓縮的部分:mod_brotli 需要 2.4.26 以上,舊版沒有這個模組;mod_deflate 則是 2.4 全系列都有。要查自己的版本,主機面板通常會標,或看 curl -sI 回應的 Server: 標頭(部分主機會關閉版本顯示)。


📎 參考資料來源

📖 第一級|廠商官方:

⚠️ 本文核心事實以第一級為準;全文未引用第二級來源。

📅 本文查證戳記:2026-07-15 依據 Apache HTTP Server 2.4 官方文件撰寫,非實機實測。

若你在後續版本遇到規則失效,歡迎在留言區回報,站長會更新文章。

廣告