<-
Apache > HTTP 伺服器 > 文件 > 2.4 版本 > 操作指南/教學

Apache httpd 教學:伺服器端包含介紹

伺服器端包含提供一種方法,可以把動態內容加入現有的 HTML 文件中。

Support Apache!

請參照

top

簡介

這篇文章處理伺服器端包含,通常簡稱 SSI。在這篇文章中,我將談論如何設定你的伺服器允許 SSI,並且介紹一些基本的 SSI 技巧,以將動態內容加入你現有的 HTML 頁面中。

在文章的後段,我們將討論一些比較進階,且可以藉由 SSI 達成的功能,例如在 SSI 指令中加入條件陳述式。

top

什麼是 SSI?

SSI (伺服器端包含) 是放在 HTML 頁面中的指令,並在頁面送出的同時在伺服器上評估。它可以讓你將動態產生的內容加入現有的 HTML 頁面,而無需透過 CGI 程式或其他動態技術來提供整個頁面。

例如,你可以在現有的 HTML 頁面中放置一個指令,例如

<!--#echo var="DATE_LOCAL" -->

然後,當頁面送出時,這個片段將會被評估,並以它的值替換

Tuesday, 15-Jan-2013 19:28:54 EST

選擇何時使用 SSI 以及何時完全透過某些程式產生網頁,通常取決於網頁中有多少內容是靜態的,以及多少內容每次送出網頁時需要重新計算。SSI 是新增小段資訊的絕佳方式,例如顯示在上面的目前時間。但是如果網頁大部分的內容在送出時才產生,則需要尋找其他解決辦法。

top

設定伺服器以允許 SSI

要在伺服器上允許 SSI,您必須在 httpd.conf 檔案或 .htaccess 檔案中,擁有下列指令

Options +Includes

它告訴 Apache 您想要允許對檔案進行 SSI 指令解析。請注意,大多數設定都包含多個 Options 指令,可以用來覆寫彼此。您可能需要將 Options 套用在您希望啟用 SSI 的特定目錄中,以確保它會最後評估。

並非任何檔案都會進行 SSI 指令的解析。您必須告訴 Apache 哪些檔案應該進行解析。有兩個方法可以做到這一點。您可以告訴 Apache 解析任何具有特定檔案副檔名的檔案,例如 .shtml,使用下列指令

AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

此方法的一個缺點是,如果您想要將 SSI 指令新增到現有網頁,則必須變更該網頁的名稱,並變更所有連結到該網頁的連結,才能給予它 .shtml 副檔名,才能執行那些指令。

另一個方法是使用 XBitHack 指令

XBitHack on

XBitHack 會告訴 Apache 如果檔案設定了執行位元,就解析該檔案的 SSI 指令。因此,要將 SSI 指令新增到現有網頁,不需要變更檔案名稱,只需要使用 chmod 命令使檔案可以執行即可。

chmod +x pagename.html

簡短說明一下不建議做的事情。您偶爾會看到有人建議,直接告訴 Apache 解析所有 .html 檔案的 SSI,這樣就不必處理 .shtml 檔案名稱。這些人可能不知道 XBitHack。請記住,這樣做會讓 Apache 讀取傳送給客戶端的每個檔案,即使它們不包含任何 SSI 指令。這會讓速度慢很多,並不是個好主意。

當然,在 Windows 中沒有所謂的執行位元設定,這會稍微限制您的選項。

在預設設定中,Apache 不會在 SSI 網頁上傳送上次修改日期或內容長度 HTTP 標頭,因為這些值對於動態內容來說很難計算。這可能會讓您的文件無法快取,並導致客戶端效能顯著降低。有兩個方法可以解決這個問題

  1. 使用 XBitHack Full 組態。這會指示 Apache 只查看原來要求的檔案日期來判斷上次修改日期,而忽略任何包含檔案的修改日期。
  2. 使用 mod_expires 提供的指令,在檔案上設定明確的過期時間,這樣可以讓瀏覽器和代理伺服器知道暫存這些檔案是可以接受的。
top

基本的 SSI 指令

SSI 指令有下列語法

<!--#function attribute=value attribute=value ... -->

其格式就像 HTML 註解,因此如果你沒有正確啟用 SSI,瀏覽器會忽略該指令,但它仍然會顯示在 HTML 原始碼中。如果你正確地設定了 SSI 組態,指令會以其結果取代。

function 可以是許多項目的其中之一,而在本系列的下一篇文章中,我們會進一步探討大部分的項目。以下是你可以使用 SSI 執行的部分範例,供你參考

今天的日期

<!--#echo var="DATE_LOCAL" -->

echo函數僅會輸出變數的值。有許多標準變數,其中包括一整組可供 CGI 程式使用的環境變數。此外,你可以使用 set 函數定義自己的變數。

如果你不喜歡日期的列印格式,你可以使用 config 函數,並透過 timefmt 屬性來修改該格式。

<!--#config timefmt="%A %B %d, %Y" -->
今天是 <!--#echo var="DATE_LOCAL" -->

檔案的修改日期

此文件最近修改於 <!--#flastmod file="index.html" -->

這個函數也可依 timefmt 格式組態設定。

包含 CGI 程式的結果

這是 SSI 相當常見的用途 - 輸出 CGI 程式的結果,例如每個人最喜歡的「點閱次數計數器」。

<!--#include virtual="/cgi-bin/counter.pl" -->

top

更多的範例

以下是使用 SSI 在 HTML 文件中執行的部分範例。

本文件修改於何時?

稍早我們提到你可以使用 SSI 告知使用者文件最近修改的時間。然而,實際執行的方法有點疑問。將下列程式碼置於你的 HTML 文件中,即可在你的頁面上加上時間戳。當然,你必須正確啟用 SSI,如上所述。

<!--#config timefmt="%A %B %d, %Y" -->
檔案最後修改時間 <!--#flastmod file="ssi.shtml" -->

當然,你必須將 ssi.shtml 替換為你實際要引用的檔案名稱。如果你只是想找一段可用於貼上到任何檔案的通用程式碼,這麼做比較不方便,因此你可能想改用 LAST_MODIFIED 變數

<!--#config timefmt="%D" -->
此檔案最後修改於<!--#echo var="LAST_MODIFIED" -->

關於timefmt格式的更多詳細資料,請前往您最喜歡的搜尋網站並搜尋strftime。語法相同。

包含標準的頁腳

如果您管理的多個頁面組成一個網站,您可能會發現對這些頁面進行變更可能是一種苦差事,尤其是當您試著在所有這些頁面維持某種標準樣式時。

使用包含檔作為標頭和/或頁腳可以減輕這些更新的負擔。您只需要建立一個頁腳檔,然後將它與每個頁面包含於include SSI 命令中。include函數可以用file屬性或virtual屬性來決定要包含的文件。file屬性是檔案路徑,從目前的目錄開始。這表示它不能是絕對路徑(由「/」開頭),也不能將「../」包含於路徑中。virtual屬性可能是更有用的,並且應指定相對於正在顯示的文件的網址。它可以用「/」開頭,但必須和正在顯示的文件位於同一個伺服器上。

<!--#include virtual="/footer.html" -->

我經常會合併最後二個項目,在要包含的頁腳檔中置入 LAST_MODIFIED 指示詞。SSI 指示詞可以包含在包含檔中,並且包含可以巢狀—也就是說,包含檔可以包含另一個檔,依此類推。

top

我還可以設定哪些項目?

除了設定時間格式之外,您還可以設定其他二個項目。

通常,當您的 SSI 指示詞出錯時,您會收到「處理此指令時出錯」的訊息

[an error occurred while processing this directive]

如果您想要將此訊息改成其他訊息,您可以對config函數使用errmsg屬性

<!--#config errmsg="[It appears that you don't know how to use SSI]" -->

希望最終使用者永遠不會看到此訊息,因為在您的網站正式上線之前,您已解決了所有 SSI 指示詞的問題。(是這樣吧?)

您也透過sizefmt屬性設定檔案大小傳回的格式。您可以指定bytes取得完全的位元組計數,或指定abbrev取得簡短的 Kb 或 Mb 數值(視情況而定)。

top

執行命令

以下是您可以利用exec函數執行的其他功能。您實際上可以用 shell(精確地說就是/bin/sh)—或 DOS Shell(如果您使用 Win32)—讓 SSI 執行命令。例如,下列程式碼將提供您一個目錄清單。

<pre>
<!--#exec cmd="ls" -->
</pre>

或是在 Windows 中執行

<pre>
<!--#exec cmd="dir" -->
</pre>

在 Windows 上可能會注意到使用此指令產生一些奇怪的格式,因為從「目錄」(dir) 輸出的內容會包含字串「<dir>」,這會讓瀏覽器感到困惑。

請注意,這個功能非常危險,因為它會執行嵌入於 exec 標籤的任何程式碼。如果您有讓使用者能編輯網頁上內容的情形,例如以「留言簿」的方式,請務必停用此功能。使用 Options 指令的 IncludesNOEXEC 引數,您可以允許 SSI,但不允許 exec 功能。

top

進階 SSI 技術

除了顯示內容以外,Apache SSI 也提供設定變數,以及在比較和條件判斷中使用這些變數的選項。

設定變數

使用 set 指令,您可以設定變數供日後使用。我們稍後會在討論中用到這個,因此我們將在這裡說明。語法如下所示:

<!--#set var="name" value="Rich" -->

除了像這樣將值設定為文字字串之外,您也可以使用其他變數,包括環境變數或上面討論的變數 (例如 LAST_MODIFIED),來將值指定給您的變數。在變數名稱之前使用美元符號 ($),表示內容是變數而非文字字串。

<!--#set var="modified" value="$LAST_MODIFIED" -->

若要在變數值中放入一個文字美元符號,您需要使用反斜線作為美元符號的跳脫字元。

<!--#set var="cost" value="\$100" -->

最後,如果您想將一個變數置於較長的字串中間,而且變數的名稱可能會與其他字元連在一起,因此與那些字元混淆,則可以將變數的名稱置於大括號中,以消除這種混淆。(很難想出一個真正好的範例,但希望您能理解要點。)

<!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" -->

條件式運算式

現在我們有了變數,並能夠設定和比較它們的值,我們可以使用它們來表達條件式。這讓 SSI 成為一種微型程式語言。mod_include 模組提供一個 ifelifelseendif 結構,用於建立條件式陳述式。這允許您有效地從一個實際頁面中產生多個邏輯頁面。

這個條件式結構如下所示:

<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->

一個 test_condition 可以是任何類型的邏輯比較 - 無論是將值互相比較,或測試特定值的「真假」。(給定字串如果是非空的,就是真。)有關所有可用的比較運算子的完整清單,請參閱 mod_include 文件。

例如,如果您想根據一天中的時間自訂網頁上的文字,可以在 HTML 頁面中放入以下食譜

早上好 <!--#if expr="%{TIME_HOUR} <12" -->
下午好!
<!--#else -->
下午好!
<!--#endif -->

在條件式陳述句中可以使用其他變數 (您定義的變數或一般環境變數)。有關運算式評估引擎的更多資訊,請參閱 Apache HTTP Server 中的運算式

透過 Apache 具有使用 SetEnvIf 指令和相關指令設定環境變數的功能,這個功能讓您可以在伺服器端執行各種動態內容,而不必訴諸於完整的網頁應用程式。

top

結論

SSI 絕對不能取代 CGI 或用於產生動態網頁的其他技術。但它是一種極佳的方式,可以在不進行大量額外工作的情況下,將少量動態內容新增到頁面中。

語言: 英文  |  西班牙文  |  法文  |  日文  |  韓文 

top

意見

注意
這裡不是問與答專區。放在這裡的意見應該指向如何改善文件或伺服器,且如果已實施,或被認為無效/離題,可能會被我們的管理員移除。有關如何管理 Apache HTTP Server 的問題應導向我們的 IRC 頻道,#httpd,在 Libera.chat 上,或寄送至我們的 郵件清單