<-
Apache > HTTP Server > 說明文件 > 版本 2.4 > 模組

Apache 模組 mod_headers

可用語言:  en  |  fr  |  ja  |  ko 

說明HTTP 要求和回應標頭的客製化
狀態擴充
模組識別碼headers_module
來源檔案mod_headers.c

摘要

此模組提供指令,用於控制和修改 HTTP 要求和回應標頭。標頭可以合併、取代或移除。

Support Apache!

主題

指令

錯誤修正檢查表

另見

top

處理順序

mod_headers 所提供的指令可以在伺服器組態裡的幾乎任何位置,而且可以使用 組態區段 將它們的範疇限制住。

處理順序很重要,它會受到組態檔中的順序和 組態區段 中的位置影響。如果反過來,這兩個指令會有不同的效果

RequestHeader append MirrorID "mirror 12"
RequestHeader unset MirrorID

這樣一來,MirrorID 標頭就不會設定。如果反過來,MirrorID 標頭就會設定為「鏡像 12」。

top

早期和晚期處理

mod_headers 可以套用在要求的早期或後期。一般模式是晚期,Request 標頭會在執行內容產生器之前立即設定,Response 標頭則在回應經由網路傳送出去的時候設定。請在營運中的伺服器中持續使用晚期模式。

早期模式是設計給開發人員當作測試/除錯輔助工具。有使用 early 關鍵字定義的指令會在處理要求的一開始就設定。這表示它們可以用於模擬不同的要求和設定測試案例,但這也表示在產生 Response 之前,標頭可能會隨時被其他模組變更。

由於早期指令是在 Traverse 請求路徑的設定檔之前處理,所以僅能於主伺服器或虛擬主機的背景設定早期標頭。早期指令無法依賴請求路徑,因此在 <Directory><Location> 等背景使用時,將會失敗。

top

範例

  1. 將所有以「TS」開頭的請求標頭複製到回應標頭中
    Header echo ^TS
  2. 加入標頭 MyHeader,到回應中,其中包含請求接收的時間戳記,及開始提供請求服務的所花費時間。此標頭可用於客戶端了解伺服器的負載,或解除客戶端和伺服器間的瓶頸。
    Header set MyHeader "%D %t"

    將這個標頭加入回應

    MyHeader: D=3775428 t=991424704447256

  3. 對 Joe 說哈囉
    Header set MyHeader "Hello Joe. It took %D microseconds for Apache to serve this request."

    將這個標頭加入回應

    MyHeader: Hello Joe. It took D=3775428 微秒,Apache 才能提供此請求服務。

  4. 僅在請求中存在標頭 MyRequestHeader 的情況下,將 MyHeader 有條件地傳送至回應中。這有助於根據某些客戶端刺激建立標頭。請注意,此範例需要 mod_setenvif 模組的服務。
    SetEnvIf MyRequestHeader myvalue HAVE_MyRequestHeader
    Header set MyHeader "%D %t mytext" env=HAVE_MyRequestHeader

    如果 HTTP 請求上存在標頭 MyRequestHeader: myvalue,回應將包含下列標頭

    MyHeader: D=3775428 t=991424704447256 mytext

  5. 透過將 Destination 標頭中的 https: 改為 http: 的方式,啟用 DAV 在 Apache 上透過 SSL 硬體執行 HTTP (問題說明)
    RequestHeader edit Destination ^https: http: early
  6. 在多個非獨佔條件下設定相同的標頭值,但不要在最終標頭中重複該值。如果所有下列條件都套用於請求(即,如果請求包含 CGINO_CACHENO_STORE 環境變數)
    Header merge Cache-Control no-cache env=CGI
    Header merge Cache-Control no-cache env=NO_CACHE
    Header merge Cache-Control no-store env=NO_STORE

    則回應將包含下列標頭

    Cache-Control: no-cache, no-store

    如果使用 append 取代 merge,則回應將包含下列標頭

    Cache-Control: no-cache, no-cache, no-store

  7. 僅在客戶端未傳送 Cookie 來的狀況下設定測試 Cookie
    Header set Set-Cookie testcookie "expr=-z %{req:Cookie}"
  8. 對 HTTP 狀態碼為 200 的回應加入快取標頭
    Header append Cache-Control s-maxage=600 "expr=%{REQUEST_STATUS} == 200"
top

標頭 指令

說明設定 HTTP 回應標頭
語法標頭 [條件] 新增|追加|回應|編輯|編輯*|合併|設定|setifempty|取消設定|註解 標頭 [[expr=] [替換] [早期|env=[!]變數名稱|expr=表示式]]
內容伺服器設定檔、虛擬主機、目錄、.htaccess
覆寫FileInfo
狀態擴充
模組mod_headers
相容性SetIfEmpty 可用於 2.4.7 或後續版本,expr=value 可用於 2.4.10 或後續版本

此指令可以取代、合併或移除 HTTP 回應標頭。標頭是在執行內容處理器和輸出篩選器之後修改,允許修改傳出的標頭。

選擇性的 條件 參數決定這個指令將針對哪個回應標頭的內部表格執行:已成功 (預設值、可省略) 或 永遠。兩個清單之間的差異是後者中包含的標頭會加入回應,即使有錯誤,在內部重新導向(例如 ErrorDocument 處理常式)中也被留存。另請注意在某些場景同時對這兩個條件重複這個指令是有意義的,因為相對於現有標頭,永遠 並非 已成功 的超集

已成功永遠 之間的差異在於 httpd 儲存 HTTP 回應的標頭方式而產生的功能,因為它沒有提供任何「標準化」的單一標頭清單。如果在撰寫組態時沒有記住以下概念,可能會產生的主要問題是某些 HTTP 回應最終會出現重複標頭 (讓使用者感到困惑,甚至是 HTTP 客戶端)。例如假設您有一個簡單的 PHP 代理程式設定,使用 mod_proxy_fcgi,您的後端 PHP 腳本會將 X-Foo: bar 標頭加到每個 HTTP 回應中。如上所述, mod_proxy_fcgi 使用 永遠 表格儲存標頭,所以類似下列的組態最終會產生錯誤的結果,也就是標頭重複出現兩個值

# X-Foo's value is set in the 'onsuccess' headers table
Header set X-Foo: baz

為了規避這個限制,有一些已知的組態模式可以協助,例如下列模式

# 'onsuccess' can be omitted since it is the default
Header onsuccess unset X-Foo
Header always set X-Foo "baz"

在前面所述的 條件 參數中,您可以根據 HTTP 狀態碼限制動作,例如代理或 CGI 要求。請參閱上方的區段中使用 %{REQUEST_STATUS} 的範例

執行動作取決於第一個參數 (如果指定 條件 則為第二個參數)。這可以是下列值之一

警告

請在開始閱讀動作清單前,先閱讀上面所述的 永遠已成功 標頭清單的差異,因為該重要概念仍然適用。實際上,每一個動作都如同所述執行,但只針對目標標頭清單執行

add
即使標頭已經存在,回應標頭也會加入既有標頭集中。這可能會導致兩個(或更多)標頭擁有相同名稱。這可能會造成無法預期的後果,建議使用 setappendmerge 取代。
append
回應標頭也會附加上與其同名的既有標頭。當將新值合併至既有標頭時,會以逗號將其與既有標頭分隔。這是 HTTP 提供標頭多個值的標準方法。
echo
包含此名稱的請求標頭將會回顯在回應標頭中。 header 可能為 正規表示式value 必須省略。
edit
edit*
如果這個回應標頭存在,其值會根據 正規表示式 搜尋和取代的方式進行轉換。 value 參數為 正規表示式,而 replacement 則為替換字串,其中可以包含反向參照或格式規格符。 edit 表格會在標頭值中配對和取代一次,而 edit* 表格會取代搜尋模式中每個執行個體(如果出現的次數不只一次)。
merge
回應標頭也會附加上與其同名的既有標頭,除非要附加的值已出現在標頭中以逗號分隔的數值清單中。當將新值合併至既有標頭時,會以逗號將其與既有標頭分隔。這是 HTTP 提供標頭多個值的標準方法。值會以大小寫敏感方式比對,且在處理完所有格式規格符之後才比對。雙引號內的視為與其他未加引號且相同的數值不同。
set
回應標頭已設定,將具有此名稱的所有先前標頭取代。 value 可以是格式化字串。
setifempty
請求標頭已設定,但前提是沒有其他具有此名稱的先前標頭。
Content-Type 標頭是特殊的使用案例,因為有可能已決定其值,但在評估 setifempty 時,標頭並非回應的一部分。在此使用案例中,較保險的做法是使用 set,例如以下範例
Header set Content-Type "text/plain" "expr=-z %{CONTENT_TYPE}"
unset
這個名稱的回應標頭會移除(如果存在)。如果有許多相同名稱的標頭,會全部移除。 value 必須省略。
note
具備標頭名稱 header 的值會複製到內部備註中,而其名稱由 value 提供。如果透過 CGI 或代理資源傳送的標頭已設定為清除,但應同時記錄,則此動作會很有用。
於 2.4.7 後的版本中提供。

此引數後面會接續一個 標頭 名稱,此名稱可以包含結尾冒號,但不是必須的。對於 setappendmergeaddunsetedit,大小寫不分。echo標頭 名稱會區分大小寫,而且可以是 正規表達式

對於 setappendmergeadd 指定為下一個引數。如果 包含空白,應該以雙引號將其包住。 可以是字串、包含 mod_headers 特定格式指定詞 (和字元字面值) 的字串,或是以 expr= 為字首的 ap_expr 運算式。

中允許使用下列格式指定詞

格式說明
%% 百分比符號
%t 自紀元起 (1970 年 1 月 1 日) 以微秒為單位以協調世界時收到要求的時間。此值的前面有 `t=`。
%D 從收到要求到傳送標頭的時間。這是一個衡量要求期間的標準。此值的前面有 `D=`。此值以微秒為單位。
%l 實際伺服器本身的目前負載平均值。它設計為揭露藉由 getloadavg() 取得的值,而且這代表目前的負載平均值、5 分鐘平均值和 15 分鐘平均值。此值的前面有 `l=`,每個平均值中間以 `/` 分隔。
適用於 2.4.4 和後續版本。
%i http 的目前閒置百分比 (0 到 100),根據可用的程序和執行緒。此值的前面有 `i=`。
適用於 2.4.4 和後續版本。
%b http 的目前忙碌百分比 (0 到 100),根據可用的程序和執行緒。此值的前面有 `b=`。
適用於 2.4.4 和後續版本。
%{VARNAME}e 環境變數 VARNAME 的內容。
%{VARNAME}s 如果已啟用 mod_sslSSL 環境變數 VARNAME 的內容。

注意

%s 格式指定詞只存在於 Apache 2.1 和後續版本中;它可以用來取代 %e,以避免啟用 SSLOptions +StdEnvVars 的負擔。如果無論如何都必須因為其他理由而啟用 SSLOptions +StdEnvVars%e 將比 %s 更有效率。

運算式值的注意事項

當值參數使用 ap_expr 剖析器時,有些運算式語法會和評估布林運算式的範例不同,例如 <If>

  • 語法的起點是 '字串',而不是 '運算式'。
  • 函數呼叫使用 %{funcname:arg} 語法,而不是 funcname(arg)。
  • 目前無法由這個起點存取多重引數函數
  • 引用整個參數,例如
    Header set foo-checksum "expr=%{md5:foo}"

對於 edit,有 value 參數,其為 正規表示法,以及額外的 replacement 字串。從版本 2.4.7 開始,取代字串也可以包含格式說明符。

Header 指令之後可以接續額外的參數,其可以是以下任何一個

early
指定 早期處理
env=[!]varname
如果 環境變數 varname 存在,則指令會應用。varname 前面的 ! 會反轉測試,因此只有在 varname 未設定時,指令才會套用。
expr=expression
只有在 expression 評估為 true 時,才會應用該指令。語法和評估表達式的詳細資訊在 ap_expr 說明文件中記錄。
# This delays the evaluation of the condition clause compared to <If>
Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path.php$#"

除了 早期 模式,會在將回應傳送至網路之前處理 Header 指令。這表示可以設定和/或覆寫大部分標頭,HTTP 標頭篩選器所新增的某些標頭除外。在 2.2.12 之前,無法使用此指令變更內容類型標頭。

top

RequestHeader 指令

說明設定 HTTP 要求標頭
語法RequestHeader add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]]
內容伺服器設定檔、虛擬主機、目錄、.htaccess
覆寫FileInfo
狀態擴充
模組mod_headers
相容性SetIfEmpty 可用於 2.4.7 或後續版本,expr=value 可用於 2.4.10 或後續版本

這個指令可以取代、合併、變更或移除 HTTP 要求標頭。標頭會在執行內容處理常式之前修改,允許修改輸入標頭。它執行的動作由第一個參數決定。可能會是以下值之一

add
要求標頭新增到現有標頭組中,即使此標頭已存在也是如此。這可能會導致兩個(或更多)標頭具有相同的名稱。這可能會導致無法預見的後果,且通常應使用 setappendmerge 代替。
append
要求標頭附加到任何具有相同名稱的現有標頭。當新值合併到現有標頭時,將以逗號將其與現有標頭分隔。這是 HTTP 給予標頭多個值的標準方法。
edit
edit*
如果此要求標頭存在,其值會根據 正規表示法 搜尋和取代進行轉換。value 參數是 正規表示法,而 replacement 是取代字串,其中可能包含反向參照或格式說明符。edit 格式只會在標頭值中配對和取代一次,而 edit* 格式會取代搜尋模式的每個執行個體(如果它出現不止一次)。
merge
除非要附加的值已經出現在現有標頭的逗號分隔值清單中,否則請求標頭會附加到同名的任何現有標頭中。當新值合併到現有標頭時,會以逗號與現有標頭分隔。這是 HTTP 提供給標頭多重值的標準方式。會區分大小寫地比較值,並且處理完所有格式規範器之後再進行比較。包含在雙引號中的值會視為與其他相同的不含引號值不同。
set
設定請求標頭,用此名稱取代任何先前的標頭。
setifempty
請求標頭已設定,但前提是沒有其他具有此名稱的先前標頭。
於 2.4.7 後的版本中提供。
unset
如果存在此名稱的請求標頭,則會移除此請求標頭。如果有多個同名的標頭,全部都會被移除。必須省略。

後接這個引數的是標頭名稱,可包括結尾的冒號,但不是必要。標記大小寫無關。對於 設定附加合併新增 被提供為第三個引數。如果 包含空格,則應加上雙引號括住。對於 取消設定,不應提供 可以是字串或包含格式規範器的字串,或兩者的組合。支援的格式規範器與 標頭 相同,請參閱該處以取得詳細資訊。對於 編輯,需要一個 和一個 取代,分別是一組 正規表示法 和一個取代字串。

RequestHeader 指令後面可接續一個附加引數,可能是以下任何一種

early
指定 早期處理
env=[!]varname
如果 環境變數 varname 存在,則指令會應用。varname 前面的 ! 會反轉測試,因此只有在 varname 未設定時,指令才會套用。
expr=expression
只有在 expression 評估為 true 時,才會應用該指令。語法和評估表達式的詳細資訊在 ap_expr 說明文件中記錄。

除了在 早期 模式中,RequestHeader 指令在處理程式在修正階段執行請求之前會進行處理。這應該允許瀏覽器產生或 Apache 輸入濾器產生之標頭被覆寫或修改。

可用語言:  en  |  fr  |  ja  |  ko 

top

註解

請注意
這裡不是問答區。放入這裡的意見應指向改善文件或伺服器的建議,並且如果已經實作或被視為無效/離題,我們的管理員可能會移除它們。關於如何管理 Apache HTTP 伺服器的問題應導向我們的 IRC 頻道 #httpd,位在 Libera.chat,或傳送至我們的 郵件清單