Apache HTTP Server 2.4 版
簡介 | 伺服器解析 HTML 文件(伺服器端包含) |
---|---|
狀態 | 基本 |
模組識別 | include_module |
原始檔 | mod_include.c |
此模組提供一個會在檔案送出給客戶端之前處理這些檔案的篩選器。處理動作由格式特殊的 SGML 註解控制,稱為 元素。這些元素容許使用條件式文字、包含其他檔案或程式,以及設定和列印環境變數。
伺服器端包含由 INCLUDES
篩選器 實作。如果包含伺服器端包含指令的文件套用 .shtml 副檔名,下列指令將讓 Apache 剖析這些文件,並將結果文件指定為 text/html
格式。
AddType text/html .shtml AddOutputFilter INCLUDES .shtml
針對包含 shtml 檔案的目錄,必須輸入下列指令(通常在 <Directory>
區段,但如果設定了 AllowOverride
Options
,這個指令在 .htaccess
檔案中也有效)
Options +Includes
基於向下相容性的考量,server-parsed
處理模組 也會啟用 INCLUDES 篩選器。此外,Apache 會為任何文件類型為 text/x-server-parsed-html
或 text/x-server-parsed-html3
的文件啟用 INCLUDES 篩選器(而產生的輸出文件類型會是 text/html
)。
如需深入了解,請參閱我們的 伺服器端包含教學。
預設情況下,已處理伺服器端包含的檔案不再接受包含 PATH_INFO
(尾隨路徑資訊)的要求。您可以使用 AcceptPathInfo
指令設定伺服器,以接受包含 PATH_INFO
的要求。
文件會以 HTML 文件的型式剖析,並將特殊指令嵌入為 SGML 註解。指令的語法為
<!--#element attribute=value attribute=value ... -->
value 通常會 enclose 在雙引號中,但也可以使用單引號('
)和反引號(`
)。許多指令只允許單一的屬性-值配對。請注意,註解終止符(-->
)之前應該要有空白,以確保它不會被視為 SSI 代碼的一部分。另外,開頭的 <!--#
是一個代碼,不可包含任何空白。
允許的組成元件列在下列表格中
組成元件 | 簡介 |
---|---|
註解 |
SSI 註解 |
設定 |
設定輸出格式 |
echo |
列印變數 |
執行 |
執行外部程式 |
fsize |
列印檔案大小 |
flastmod |
列印檔案的上次修改時間 |
包含 |
包含檔案 |
printenv |
列印所有可用的變數 |
set |
設定變數值 |
除了 mod_include
之外,其他模組也可以定義 SSI 組成元件。實際上,mod_cgi
提供了 exec
組成元件,且只有在載入此模組時才會提供這個元件。
此指令不會輸出任何內容。它唯一的用途是在檔案中新增註解。這些註解不會列印出來。
此語法可在 2.4.21 及更新版本使用。
<!--#comment Blah Blah Blah -->
或
<!--#comment text="Blah Blah Blah" -->
此指令控制剖析的各項設定。有效的屬性為
echomsg
(Apache 2.1 及更新版本)若 echo
元素嘗試迴顯未定義的變數 value 會傳送一個訊息回用戶端。這會覆寫任何 SSIUndefinedEcho
指令。
<!--#config echomsg="[值未定義]" -->
errmsg
若分析文件時發生錯誤,value 會傳送一個訊息回用戶端。這會覆寫任何 SSIErrorMsg
指令。
<!--#config errmsg="[糟糕,出了點問題。]" -->
sizefmt
顯示檔案大小時,value 會設定要使用的格式。有效值為 bytes
(以位元組計數)或 abbrev
(以 Kb 或 Mb 計數,視情況而定),例如大小 1024 位元組將印出為「1K」。
<!--#config sizefmt="abbrev" -->
timefmt
印出日期時,value 是 strftime(3)
函式庫常式要使用的字串。
<!--#config timefmt=""%R, %B %d, %Y"" -->
此命令會印出下方定義的 include 變數 之一。如果該變數未設定,結果將由 SSIUndefinedEcho
指令決定。列印的任何日期都會受到目前設定的 timefmt
約束。
屬性
var
decoding
指定 Apache 是否應從變數中去除編碼,然後再進一步處理此變數。預設值為 none
,表示不執行任何解碼。如果設定為 url
,將執行 URL 解碼(也稱為百分比編碼;適用于連結中的網址)。如果設定為 urlencoded
,將去除與 application/x-www-form-urlencoded 相容的編碼(在查詢字串中找到)。如果設定為 base64
,將解碼 base64,如果設定為 entity
,將去除 HTML 實體編碼。解碼是在對變數執行任何進一步編碼之前執行。可以透過指定多個逗號分隔的編碼來去除多個編碼。解碼設定將持續有效,直到遇到下一個解碼屬性或元素結束為止。
若要讓 decoding
屬性發揮作用,它必須先於對應的 var
屬性。
encoding
指定 Apache 輸出變數中的特殊字元之前如何編碼。如設定為 none
,則不執行編碼。如設定為 url
,則會執行 URL 編碼(又稱為 %-編碼;適合用在連結中的網址等)。如設定為 urlencoded
,則會改為執行與 application/x-www-form-urlencoded 相容的編碼,並應與查詢字串一併使用。如設定為 base64
,則會執行 base64 編碼。在 echo
元素的開頭,預設設定為 entity
,產生實體編碼(適用於區塊等級 HTML 元素,例如段落文字)。這可以透過新增一個 encoding
屬性來變更,而且這個屬性會維持效力,直到遇到下一個 encoding
屬性或元素結束,以先發生的為準。
encoding
屬性必須先於對應的 var
屬性,才能發揮作用。
<!--#echo encoding="entity" var="QUERY_STRING" -->
exec
指令執行指定的 shell 指令或 CGI 指令碼。它需要 mod_cgi
出現在伺服器中。如果 選項
IncludesNOEXEC
被設定,此指令就會完全停用。有效的屬性為
cgi
這個值指定一個到 CGI 指令碼的(%-編碼)網址路徑。如果路徑不是以斜線(/)開頭,則視為相對應於目前的文件。透過此路徑參考到的文件會被呼叫為 CGI 指令碼,即使伺服器平常不會將它識別為 CGI 指令碼也是一樣。但是,該指令碼所在的目錄必須已啟用 CGI 指令碼(透過 ScriptAlias
或 選項
ExecCGI
)。
CGI 指令碼會取得來自客戶端的原始要求的 PATH_INFO
和查詢字串 (QUERY_STRING
);這些不能在網址路徑中指定。除了標準的 CGI 環境外,include 變數也會提供給指令碼。
<!--#exec cgi="/cgi-bin/example.cgi" -->
如果指令碼傳回 Location:
標頭而不是輸出,它就會被轉為 HTML anchor。
include virtual
元素應該優先於 exec cgi
使用。特別是,如果您需要透過查詢字串將額外的參數傳遞給 CGI 程式,則無法使用 exec cgi
來執行此動作,但可以使用 include virtual
來執行此動作,如下所示
<!--#include virtual="/cgi-bin/example.cgi?argument=value" -->
cmd
伺服器會使用 /bin/sh
執行指定的字串。除了通常的一組 CGI 變數外,還可以對指令碼使用 include 變數。
使用 #include virtual
幾乎在所有情況都比使用 #exec cgi
或 #exec cmd
來得合適。前者(#include virtual
)使用標準 Apache 子請求機制來包含檔案或指令碼。它經過更廣泛地測試和維護。
此外,在某些平台(例如 Win32)和在使用 suexec 的 unix 上,你無法在 exec
指令中將參數傳遞到指令,或是包含指令中其他空白。因此,儘管下列指令在 unix 的非 suexec 組態下會運作,它將無法在 Win32 或執行 suexec 時產生預期結果
<!--#exec cmd="perl /path/to/perlscript arg1 arg2" -->
這個指令印出指定檔案的大小,受 sizefmt
格式規範影響。屬性
file
這個檔案的大小為 <!--#fsize file="mod_include.html" --> bytes。
file
的值不能以斜線 (/
) 開頭,它也不能包含 ../
這個字串作為參照目前資料夾上層或文件根目錄之外的檔案。嘗試這麼做將會產生錯誤訊息:The given path was above the root path
(已傳遞的路徑高於根路徑)。virtual
這個檔案的大小為 <!--#fsize virtual="/docs/mod/mod_include.html" --> bytes。
請注意,在許多情況下,這兩個指令完全相同。然而,file
屬性不支援 URL 空間別名。
這個指令印出指定檔案的最後修改日期,受 timefmt
格式規範影響。屬性與 fsize
指令相同。
這個指令將另一個文件或檔案的文字插入到分析過的文件中。任何包括的文件都受一般存取控制影響。如果包含分析過的文件的資料夾已設定 選項 IncludesNOEXEC
,則只有文字 MIME 類型(text/plain
、text/html
等)的文件才會被包。否則,CGI 腳本會使用指令中提供完整的 URL(包含任何查詢字串)以一般的方式呼叫。
屬性定義文件的所在位置,而且可以在 include 元素中出現多次;會輪流對 include 指令提供給的每個屬性執行包含。可用的屬性如下
file
../
,也不能是一個絕對路徑。因此,您無法包含位於文件根目錄之外,或在目錄結構中位於目前文件之上的檔案。virtual
屬性應該總是優先使用它。virtual
值是一個(%編碼)URL 路徑。該 URL 不能包含一個範例或主機名稱,只能包含一個路徑和一個可選擇的查詢字串。如果它不是從正斜線(/)開頭,則它被認為與目前的文件相關。
從屬性建構一個 URL,且如果由客戶端存取該 URL,伺服器將回傳的輸出會包含在已解析的輸出中。因此,包含的檔案可以是巢狀的。
如果指定的 URL 是 CGI 程式,程式會被執行,而它的輸出會插入已解析檔案中的指令取代它。您可以在 CGI URL 中包含一個查詢字串
<!--#include virtual="/cgi-bin/example.cgi?argument=value" -->
include virtual
應該優先於 exec cgi
使用,以包含 CGI 程式的輸出至一個 HTML 文件。
如果 KeptBodySize
指令已正確設定且對這個包含的檔案有效,嘗試將 POST 請求傳送到封裝的 HTML 文件時將會傳遞至子請求作為 POST 請求。沒有該指令時,所有子請求會被處理為 GET 請求。
onerror
值是一個(%編碼)URL 路徑,如果先前嘗試包含一個檔案或虛擬屬性失敗時,會顯示它。這個屬性必須在所涵蓋的檔案或虛擬屬性之後指定,才能生效。如果嘗試包含 onerror 路徑失敗,或如果沒有指定 onerror,會包含預設的錯誤訊息。
# 簡單範例
<!--#include virtual="/not-exist.html" onerror="/error.html" -->
# 專用 onerror 路徑
<!--#include virtual="/path-a.html" onerror="/error-a.html" virtual="/path-b.html" onerror="/error-b.html" -->
這會列印一個純文字清單,列出所有現有變數及其值。特殊字元會在輸出前以實體編碼(詳細資訊請參閱 echo
元素)。沒有屬性。
<pre> <!--#printenv --> </pre>
這會設定變數的值。屬性
var
value
decoding
指定 Apache 在進一步處理變數之前是否要從變數中移除編碼。預設值為 none
,表示不進行任何解碼。如果設定為 url
、urlencoded
、base64
或 entity
,則會分別執行 URL 解碼、application/x-www-form-urlencoded 解碼、base64 解碼或 HTML 實體解碼。可以透過逗號分隔來指定多個解碼。解碼設定會持續有效,直到遇到下一個解碼屬性或元素結束為止。decoding
屬性必須 在 對應的 var
屬性之前出現才能生效。
encoding
指定 Apache 在設定特殊字元之前,如何對變數中包含的特殊字元進行編碼。預設值為 none
,表示不進行任何編碼。如果設定為 url
、urlencoding
、base64
或 entity
,則會分別執行 URL 編碼、application/x-www-form-urlencoded 編碼、base64 編碼或 HTML 實體編碼。可以透過逗號分隔來指定多個解碼。編碼設定會持續有效,直到遇到下一個編碼屬性或元素結束為止。encoding
屬性必須 在 對應的 var
屬性之前出現才能生效。編碼會在移除所有解碼後套用。
<!--#set var="category" value="help" -->
除了標準 CGI 環境中的變數之外,這些變數可用於 echo
命令、if
和 elif
,以及文件呼叫的任何程式。
DATE_GMT
DATE_LOCAL
DOCUMENT_ARGS
include
SSI 指令呼叫的子請求,QUERY_STRING
將會代表子請求的查詢字串,而 DOCUMENT_ARGS
將會代表 SSI 文件的查詢字串。(Apache HTTP Server 2.4.19 版本及後續版本才有提供)DOCUMENT_NAME
DOCUMENT_PATH_INFO
PATH_INFO
,請參閱指令 AcceptPathInfo
。DOCUMENT_URI
alias
或 directoryindex
),會顯示修改後的 URL。LAST_MODIFIED
QUERY_STRING_UNESCAPED
&
等前面加上反斜線)。如果查詢字串不存在,不會設定。如果不需要 Shell 轉譯,請使用 DOCUMENT_ARGS
。USER_NAME
變數置換出現在大部分情況的帶引號字串中,這些情況很可能作為 SSI 指令參數出現。這包含 config
、exec
、flastmod
、fsize
、include
、echo
和 set
指令。如果 SSILegacyExprParser
設為 on
,也會在條件運算子的參數中進行置換。您可以使用反斜線引號將文字美元號插入字串中
<!--#set var="cur" value="\$test" -->
如果變數參照需要置換於字元序列中間,而該字元序列可能被視為本身的有效識別碼,則可以將參照括於括弧中,這類似於 Shell 中的置換
<!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" -->
如果有 REMOTE_HOST
為 "X"
、REQUEST_METHOD
為 "Y"
,這將會導致 Zed
變數設為 "X_Y"
。
基本流程控制元素為
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
if
元素的工作原理,如同程式語言中的 if 陳述式。會評估測試條件,如果結果為 true,則會將文字包含於輸出串流中,直至下一個 elif
、else
、endif
元素。
如果原始 test_condition 為 false,elif
或 else
陳述式用於將文字置於輸出串流中。這些元素為選用項目。
endif
元素會終止 if
元素,且為必備項目。
test_condition 是一個布林表達式,遵循 ap_expr 語法。語法可以使用 SSILegacyExprParser
變更為相容於 Apache HTTPD 2.2.x。
使用 var
元素所設定的 SSI 變數會匯出至請求環境中,且可以使用 regvenv
函數存取。為了簡便,mod_include
內部也可以使用函數名稱 v
。
下列範例會在客戶端 IP 位址屬於 10.0.0.0/8 網路時,列印「來自本地網路」。
<!--#if expr='-R "10.0.0.0/8"' -->
來自本地網路
<!--#else -->
來自其他地方
<!--#endif -->
如果變數 foo
設定為值 "bar",以下範例將會印出 "foo is bar"。
<!--#if expr='v("foo") = "bar"' -->
foo is bar
<!--#endif -->
另見:Apache HTTP 伺服器中的表達式,以取得完整的參考和範例。受限 函式在 mod_include
中不可用
此部分說明了 #if expr
元素的語法,前提是將 SSILegacyExprParser
設為 on
。
字串
-A 字串
如果設定允許存取字串所代表的 URL,則為 true;否則為 false。這會在頁面上的內容對未被授權檢視 URL 的使用者隱藏時很有用,例如連結到該 URL。請注意,URL 僅測試是否會被授予存取權限,而不測試 URL 是否存在。
<!--#if expr="-A /private" -->
按一下 <a href="/private">這裡</a>,以存取私人資訊。
<!--#endif -->
string1 = string2
string1 == string2
string1 != string2
將 string1 和 string2 進行比較。如果 string2 的格式為 /string2/
,它將被視為正規表示法。正規表示法是由 PCRE 引擎實作,且語法與 perl 5 中的語法相同。請注意,==
只是 =
的別名,且行為完全相同。
如果你正在配對正向 (=
或 ==
),你可以擷取正規表示法的群組化部分。擷取的部分儲存在特殊變數 $1
.. $9
中。正規表示法配對到的整個字串儲存在特殊變數 $0
中
<!--#if expr="$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/" -->
<!--#set var="session" value="$1" -->
<!--#endif -->
string1 < string2
string1 <= string2
string1 > string2
string1 >= string2
strcmp(3)
)。因此字串 "100" 小於 "20"。( test_condition )
! test_condition
test_condition1 && test_condition2
test_condition1 || test_condition2
"=
" 和 "!=
" 的結合比 "&&
" 和 "||
" 更緊密。"!
" 的結合最緊密。因此,下列兩者是相等的
<!--#if expr="$a = test1 && $b = test2" -->
<!--#if expr="($a = test1) && ($b = test2)" -->
布林運算子 &&
和 ||
有著相同的優先權。所以如果您想更嚴格地約束這樣的運算子,您應該使用圓括號。
任何無法識別為變數或運算子的東西都被視為字串。字串也可以用引號括起來:'string'
。未加引號的字串不能包含空白(空格和標籤),因為這些是用來分隔像是變數這類的記號。如果在字串中找到了多個字串,它們會用空白串接。因此,
string1 string2
產生 string1 string2
以及
'string1 string2'
產生 string1 string2
。
如果表達式變得更複雜且速度顯著變慢,您可以嘗試根據評估規則最佳化它們
&&
和 ||
) 盡可能短路。總結前述規則後表示, mod_include
首先評估左邊的表達式。如果左邊的結果足以決定最後結果,處理程序在此處停止。否則它會評估右側並從左右兩邊的結果計算最終結果。$1
.. $9
)。如果您想查看特定表達式是如何處理的,您可以使用 -DDEBUG_INCLUDE
編譯器選項重新編譯 mod_include
。這將插入每個已解析表達式標記化程式資訊、解析樹以及如何將其評估為傳送至用戶端輸出的資訊。
所有在正規表示式中不是要作為分隔符號的斜線都必須跳脫。這與其在正規表示式引擎中的意義無關。
簡介 | 結束包含元素的字串 |
---|---|
語法 | SSIEndTag 標籤 |
預設值 | SSIEndTag "-->" |
內容 | 伺服器設定、虛擬主機 |
狀態 | 基本 |
模組 | mod_include |
此指令變更 mod_include
尋找以標記包含元素結束的字串。
SSIEndTag "%>"
簡介 | 當有 SSI 錯誤時顯示的錯誤訊息 |
---|---|
語法 | SSIErrorMsg 訊息 |
預設值 | SSIErrorMsg "[處理此指令時發生錯誤]" |
內容 | 伺服器設定、虛擬主機、目錄、.htaccess |
覆寫 | 全部 |
狀態 | 基本 |
模組 | mod_include |
指令會變更當 SSIErrorMsg
mod_include
遇到錯誤時所顯示的錯誤訊息。對於製作伺服器,建議將預設錯誤訊息變更為 "<!-- Error -->"
,這樣就不會讓訊息顯示給使用者。
此指令的效用與 <!--#config errmsg=message -->
元素相同。
SSIErrorMsg "<!-- Error -->"
簡介 | 控制是否由伺服器產生 ETags。 |
---|---|
語法 | SSIETag on|off |
預設值 | SSIETag off |
內容 | 目錄、.htaccess |
狀態 | 基本 |
模組 | mod_include |
相容性 | 可用於版本 2.2.15,以及後續版本。 |
在正常情況下,由 mod_include
篩選的檔案可能包含動態產生的元素,或獨立於原始檔案且可能已經變更的元素。結果,預設要求伺服器不要在回應中產生 ETag
標頭,方法是在要求記事中加入 no-etag
。
指令會壓制此行為,並允許伺服器產生 SSIETag
ETag
標頭。這可以用於啟用輸出的快取。請注意,後端伺服器或動態內容產生器可能會自行產生 ETag,而忽略 no-etag
,並且這個 ETag 將會被 mod_include
傳遞,而與此設定值無關。
可以採用以下值SSIETag
off
no-etag
會加入要求記事中,並要求伺服器不要產生 ETag。在伺服器忽略 no-etag
的值並產生 ETag 的狀況下,ETag 仍會被尊重。on
簡介 | 控制是否由伺服器產生 Last-Modified 標頭。 |
---|---|
語法 | SSILastModified on|off |
預設值 | SSILastModified off |
內容 | 目錄、.htaccess |
狀態 | 基本 |
模組 | mod_include |
相容性 | 可用於版本 2.2.15,以及後續版本。 |
在正常情況下,由 mod_include
篩選的檔案可能包含動態產生的元素,或獨立於原始檔案且可能已經變更的元素。結果,預設會從回應中移除 Last-Modified
標頭。
指令會覆寫此行為,並且允許在已存在的狀況下尊重 SSILastModified
Last-Modified
標頭,或是在標頭尚未存在的狀況下設定標頭。這可以用於啟用輸出的快取。
可以採用以下值SSILastModified
off
Last-Modified
標頭將會從回應中移除,除非 XBitHack
指令設定為 full
如下所述。on
Last-Modified
標頭,它會受到尊重,而且如果該回應是一個檔案,且沒有標頭,就會將它加到該回應中。SSILastModified
指令會優先於 XBitHack
。簡介 | 啟用條件表達式的相容模式。 |
---|---|
語法 | SSILegacyExprParser on|off |
預設值 | SSILegacyExprParser off |
內容 | 目錄、.htaccess |
狀態 | 基本 |
模組 | mod_include |
相容性 | 在 2.3.13 和後續版本中提供。 |
自從 2.3.13 版後,
已將 mod_include
#if
流程控制元件的條件表達式切換到新的 ap_expr
語法。這個指令允許切換到與 Apache HTTPD 第 2.2.x 版相容的 舊語法
。
簡介 | 一個開始包含元件的字串 |
---|---|
語法 | SSIStartTag 標籤 |
預設值 | SSIStartTag "<!--#" |
內容 | 伺服器設定、虛擬主機 |
狀態 | 基本 |
模組 | mod_include |
這個指令會變更
尋找要處理的包含元件的標籤字串。mod_include
如果你有 2 個伺服器會解析檔案的輸出,每個伺服器都會處理不同的命令(可能在不同的時間),你可能想要使用這個選項。
SSIStartTag "<%" SSIEndTag "%>"
上面給的範例,同時也指定了一個配對的
,將會讓你能夠使用 SSI 指令,正如以下範例所示SSIEndTag
<%printenv %>
簡介 | 設定顯示日期字串的格式 |
---|---|
語法 | SSITimeFormat 格式化字串 |
預設值 | SSITimeFormat "%A, %d-%b-%Y %H:%M:%S %Z" |
內容 | 伺服器設定、虛擬主機、目錄、.htaccess |
覆寫 | 全部 |
狀態 | 基本 |
模組 | mod_include |
當回應 DATE
環境變數時,這個指令會變更顯示日期字串的格式。格式化字串
就如同 C 標準函式庫中的 strftime(3)
。
這個指令具有和 <!--#config timefmt=格式化字串 -->
元件一樣的效果。
SSITimeFormat "%R, %B %d, %Y"
以上的指令會造成時間以「22:26, June 14, 2002」格式顯示。
簡介 | 回應一個尚未設定的變數時所顯示的字串 |
---|---|
語法 | SSIUndefinedEcho 字串 |
預設值 | SSIUndefinedEcho "(none)" |
內容 | 伺服器設定、虛擬主機、目錄、.htaccess |
覆寫 | 全部 |
狀態 | 基本 |
模組 | mod_include |
當一個變數未設定而且「回應」時,這個指令會變更
所顯示的字串。mod_include
SSIUndefinedEcho "<!-- undef -->"
簡介 | 將執行 位元組設定為檔案中 SSI 指令的解析 |
---|---|
語法 | XBitHack on|off|full |
預設值 | XBitHack off |
內容 | 伺服器設定、虛擬主機、目錄、.htaccess |
覆寫 | 選項 |
狀態 | 基本 |
模組 | mod_include |
XBitHack
指令控制對一般 html 文件的解析。此指令只影響與 MIME 類型 text/html
相關的檔案。XBitHack
指令可以接受下列值。
off
on
text/html
檔案,都會視為伺服器解析的 html 文件。full
on
指令,但它會測試群組執行位元組。如果已設定,會設定傳回檔案的 Last-modified
日期為檔案的最後修改時間。如果未設定,則不會傳送最後修改時間。設定此位元組可讓客戶端和代理快取請求的結果。除非你能確定所有可能會 #include
CGI,或在每次點選時產生不同輸出 (或在後續的請求時可能改變) 的 SSI 程式碼都未設定群組執行位元組,否則你不會想要使用 full 選項。
當 SSILastModified
指令設定為 on
時,它會優先於 XBitHack
指令。