# 服務器端包含入門
服務器端包含提供了一種對現有HTML文檔增加動態內容的方法。
## 簡介
相關模塊
* `mod_include`
* `mod_cgi`
* `mod_expires`
相關指令
* `Options`
* `XBitHack`
* `AddType`
* `SetOutputFilter`
* `BrowserMatchNoCase`
本文針對服務器端包含(SSI)討論如何配置服務器以允許SSI ,并介紹一些對現有HTML頁面增加動態內容的基本SSI技術。
本文后部將討論用SSI做一些稍微高級的事情,比如SSI指令中的條件語句。
## 什么是SSI ?
SSI是嵌入HTML頁面中的指令,在頁面被提供時由服務器進行運算,以對現有HTML頁面增加動態生成的內容,而無須通過CGI程序提供其整個頁面,或者使用其他動態技術。
至于什么時候應當用SSI ,而什么時候應當用某些程序生成整個頁面,取決于頁面中有多少內容是靜態的,又有多少內容需要在每次頁面被提供時重新計算。SSI是一種增加小段動態信息的好方法,比如當前時間。如果你的頁面大部分內容是在被提供時動態生成的,那就要另找方案了。
## 配置服務器以允許SSI
要使服務器允許SSI ,必須在`httpd.conf`或`.htaccess`文件中有如下配置:
```
Options +Includes
```
這樣就告訴服務器允許解析文件中的SSI指令。注意,在多數配置中,多個`Options`指令會互相覆蓋,所以可能需要對使用SSI的目錄專門使用一個`Options`指令,以確保其有效。
并非所有文件中的SSI指令都會被解析,必須告訴Apache應該解析哪些文件。有兩種方法使Apache解析帶有特定后綴名的文件,比如:`.shtml` ,配置如下:
```
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
```
該方法的缺點之一是,為了使文件具有`.shtml`后綴從而執行其中的指令,需要加入SSI指令的現有文件的名字,以及所有指向此頁面的連接。
另一種方法是,使用`XBitHack`指令:
```
XBitHack on
```
`XBitHack`告訴Apache解析所有設置了執行位的文件中的SSI指令。這樣,無需修改文件名,只要用`chmod`使文件變成可執行的,就可以對現有頁面增加SSI指令。
```
chmod +x pagename.html
```
這里簡要說明一點:偶然會有人向你推薦,無須用帶`.shtml`的文件名,只要使Apache解析所有`.html`文件的SSI就可以了。那些人可能沒聽說過`XBitHack` 。要知道,這樣做會使Apache在發送文件到客戶端之前通讀此文件,即使其中并沒有任何SSI指令,從而對速度有很不利的影響,所以這并不是好辦法。
當然,在Windows上,沒有對應的執行位可以設置,所以對你的配置方法就有一些限制。
在默認配置的情況下,Apache不會為SSI頁面發送最后修改日期或者內容長度的HTTP頭,因為這些值對動態頁面來說難以確定。這樣會阻止頁面被緩沖,導致客戶端性能有明顯的下降。有兩種解決方法:
1. 設置 `XBitHack Full` ,告訴Apache在判斷最后修改日期時,只查看被請求文件本身的日期,而忽略其中包含的其它文件的修改日期。
2. 使用`mod_expires`提供的指令為文件設置一個明確的過期時間,并告訴瀏覽器和代理這個文件可以被緩沖。
## 基本SSI指令
SSI指令有如下語法:
```
<!--#element attribute=value attribute=value ... -->
```
類似于HTML注釋,即使沒有正確配置SSI ,它也不會被瀏覽器顯示,但在HTML代碼中可見。而若正確配置了SSI ,則指令會被其結果所取代。
其中的元素可以有許多,我們會在下一個版本的文檔中討論其中的大多數,而在這里,僅舉幾個SSI的例子。
### 今天的日期
```
<!--#echo var="DATE_LOCAL" -->
```
`echo`元素用于顯示一個變量的值。標準變量有很多,其中包含對CGI程序有效的所有環境變量。并且還可以用`set`元素定義你自己的專用變量。
如果你不喜歡這種日期格式,可以用`config`元素的`timefmt`屬性,改變其格式。
```
<!--#config timefmt="%A %B %d, %Y" -->
Today is <!--#echo var="DATE_LOCAL" -->
```
### 文件的修改日期
```
This document last modified <!--#flastmod file="index.html" -->
```
這個元素使用`timefmt`的格式配置。
### 包含一個CGI程序的輸出結果
這也是SSI很常見的一個用途:包含一個CGI程序的輸出,比如人人喜歡的"點擊計數器"。
```
<!--#include virtual="/cgi-bin/counter.pl" -->
```
## 附加的例子
以下是一些在HTML中使用SSI的特殊例子。
### 文檔是什么時候被修改的?
前面我們提到過可以用SSI告訴用戶文檔是什么時候被修改的,但是具體實現方法卻未說明。將以下代碼放到HTML中,會在頁面中產生一個時間戳,當然,你必須首先按前面的方法啟用SSI 。
```
<!--#config timefmt="%A %B %d, %Y" -->
This file last modified <!--#flastmod file="ssi.shtml" -->
```
不用說,你應該用你實際引用的文件名來替換`ssi.shtml` ,所以,如果你想簡單地在所有文件中使用這段通用代碼以達到這個目的,這個方法就并不方便,就需要用到`LAST_MODIFIED` 變量:
```
<!--#config timefmt="%D" -->
This file last modified <!--#echo var="LAST_MODIFIED" -->
```
有關`timefmt`格式的細節,可以到[google](http://www.google.com/)查找`strftime` ,其語法是相同的。
### 包含一個標準頁腳
當你管理一個擁有許多頁面的站點,你會發現對所有頁面同時做改動是很痛苦的,尤其是在試圖對所有頁面維持某種標準視覺效果的時候。
使用包含一個頁眉/頁腳的方法,可以減輕修改的負擔。你只要制作一個頁腳文件,并用`include`命令包含到每個頁面即可。`include`元素能按`file`屬性或`virtual`屬性判斷應該包含的文件。`file`屬性是一個_相對于當前目錄_的文件路徑,即不能是一個絕對路徑(以"/"開頭)或包含"../"的路徑。`virtual`屬性可能更有用,它是一個相對于被提供的文檔的URL ,可以以"/"開頭,但必須與被提供的文檔位于同一服務器上。
```
<!--#include virtual="/footer.html" -->
```
SSI指令和頁腳文件相結合使用是很有用的,比如在頁腳文件中使用`LAST_MODIFIED`指令。SSI指令可以出現在包含文件中,而`include`可以嵌套,即一個包含文件還可以再包含另外一個。
## 我還能設置其它什么?
`config`除了能設置時間格式,還有兩種用途。
當SSI指令發生錯誤時,會產生如下消息:
```
[an error occurred while processing this directive]
```
為了改變消息的形式,可以使用`config`元素的`errmsg`屬性:
```
<!--#config errmsg="[It appears that you don't know how to use SSI]" -->
```
希望最終用戶永遠也不會看到這個消息,因為在網站投入運行之前你已經把這些問題都解決了。是嗎?
還可以使用`config`的`sizefmt`屬性設置返回的文件大小的格式,或者是以`bytes`為單位,或者是以Kb或Mb為單位的`簡寫(abbrev)`。
## 執行命令
我期望未來幾個月內能再寫一篇小型的CGI程序使用SSI的文章,而這里僅介紹`exec`的使用。SSI確實可以利用shell(`/bin/sh` ,精確地說,還可以是Win32中的DOS shell)來執行命令。下例產生一個目錄列表:
```
<pre>
<!--#exec cmd="ls" -->
</pre>
```
或者在Windows中:
```
<pre>
<!--#exec cmd="dir" -->
</pre>
```
你可能會發現,在Windows中這個指令的結果有些奇怪,`dir`的輸出中包含有字符串"<`dir`>",它會使瀏覽器產生混淆。
注意,這個功能是**極度危險**的,因為它會執行任何包含在`exec`標記中的命令。如果用戶有可能修改你的網頁內容,比如"留言本",那么你一定要關閉這個功能。可以在`Options`指令中加上`IncludesNOEXEC`參數,以關閉`exec`功能,同時又保留SSI。
## 高級SSI技術
除了分離內容,Apache SSI還有設置變量的操作,并且還可以將這些變量用在比較和條件表達式中。
### 警告
本文中討論的大多數功能僅在Apache1.2及更新版本中有效。如果你運行的不是Apache1.2及更新版本,請立刻或者盡快升級,現在就動手,我們會等你弄好了再繼續往下講。
### 設置變量
使用`set`指令可以設置變量以備后用,其語法是:
```
<!--#set var="name" value="Rich" -->
```
除了設置字面變量以外,還可以設置其他任何變量,比如[環境變量](#calibre_link-232)和此前提到過的一些變量(如`LAST_MODIFIED`),作為你的專用變量。在變量名前面綴以"$",表示它是一個變量,而不是一個字面字符串。
```
<!--#set var="modified" value="$LAST_MODIFIED" -->
```
若要在字面字符串中使用"$",必須使用轉義符號"\$":
```
<!--#set var="cost" value="\$100" -->
```
最后,如果要在較長的字符串中使用變量,可以用花括號把變量名括起來,以免變量名與其他字符混淆(要對這種情況舉例說明有點難度,但還是希望你能領會)。
```
<!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" -->
```
### 條件表達式
有了變量,就可以設置和比較它們的值以表示條件,SSI也因此成為一種簡潔的編程語言。`mod_include`提供了`if`, `elif`, `else`, `endif`等結構以構造條件語句,從同一個頁面高效地產生多個邏輯頁面。
條件結構如下:
```
<!--#if expr="test_condition" -->
<!--#elif expr="test_condition" -->
<!--#else -->
<!--#endif -->
```
_test_condition_可以是任何邏輯比較:可以是一個值和另一個值比較,也可以是測試一個特定的值是否為"真"(一個給定的字符串如果非空則為真)。完整的比較操作符列表,參見`mod_include` 。以下是可能會用到的一些例子。
在配置文件中,可以這樣設置:
```
BrowserMatchNoCase macintosh Mac
BrowserMatchNoCase MSIE InternetExplorer
```
如果客戶端在Macintosh上運行Internet Explorer,則上例設置環境變量"Mac"和"InternetExplorer"都為真。
然后,在允許SSI的文檔中,可以這樣設置:
```
<!--#if expr="${Mac} && ${InternetExplorer}" -->
Apologetic text goes here
<!--#else -->
Cool JavaScript code goes here
<!--#endif -->
```
我一點也不反對在Mac上運行IE,只是上個星期我花了好幾個小時試圖在Mac上的IE中使用JavaScript,而它在其他地方都能正常運作,以上只是一個臨時的妥協方案。
任何其他變量(或者是你定義的,或者是標準的環境變量)都可以用于條件語句。利用Apache的`SetEnvIf`以及其他相關指令設置環境變量,此功能可以很好地實現動態頁面而無須借助于CGI。
## 總結
SSI固然不能替代CGI或者其他動態頁面技術,但它是在頁面中插入眾多小型的動態片段的優秀方法,而無須大量額外的操作。
- Apache HTTP Server Version 2.2 文檔 [最后更新:2006年3月21日]
- 版本說明
- 從1.3升級到2.0
- 從2.0升級到2.2
- Apache 2.2 新特性概述
- Apache 2.0 新特性概述
- The Apache License, Version 2.0
- 參考手冊
- 編譯與安裝
- 啟動Apache
- 停止和重啟
- 配置文件
- 配置段(容器)
- 緩沖指南
- 服務器全局配置
- 日志文件
- 從URL到文件系統的映射
- 安全方面的提示
- 動態共享對象(DSO)支持
- 內容協商
- 自定義錯誤響應
- 地址和端口的綁定(Binding)
- 多路處理模塊
- Apache的環境變量
- Apache處理器的使用
- 過濾器(Filter)
- suEXEC支持
- 性能方面的提示
- URL重寫指南
- Apache虛擬主機文檔
- 基于主機名的虛擬主機
- 基于IP地址的虛擬主機
- 大批量虛擬主機的動態配置
- 虛擬主機示例
- 深入研究虛擬主機的匹配
- 文件描述符限制
- 關于DNS和Apache
- 常見問題
- 經常問到的問題
- Apache的SSL/TLS加密
- SSL/TLS高強度加密:緒論
- SSL/TLS高強度加密:兼容性
- SSL/TLS高強度加密:如何...?
- SSL/TLS Strong Encryption: FAQ
- 如何.../指南
- 認證、授權、訪問控制
- CGI動態頁面
- 服務器端包含入門
- .htaccess文件
- 用戶網站目錄
- 針對特定平臺的說明
- 在Microsoft Windows中使用Apache
- 在Microsoft Windows上編譯Apache
- Using Apache With Novell NetWare
- Running a High-Performance Web Server on HPUX
- The Apache EBCDIC Port
- 服務器和支持程序
- httpd - Apache超文本傳輸協議服務器
- ab - Apache HTTP服務器性能測試工具
- apachectl - Apache HTTP服務器控制接口
- apxs - Apache 擴展工具
- configure - 配置源代碼樹
- dbmmanage - 管理DBM格式的用戶認證文件
- htcacheclean - 清理磁盤緩沖區
- htdbm - 操作DBM密碼數據庫
- htdigest - 管理用于摘要認證的用戶文件
- httxt2dbm - 生成RewriteMap指令使用的dbm文件
- htpasswd - 管理用于基本認證的用戶文件
- logresolve - 解析Apache日志中的IP地址為主機名
- rotatelogs - 滾動Apache日志的管道日志程序
- suexec - 在執行外部程序之前切換用戶
- 其他程序
- 雜項文檔
- 與Apache相關的標準
- Apache模塊
- 描述模塊的術語
- 描述指令的術語
- Apache核心(Core)特性
- Apache MPM 公共指令
- Apache MPM beos
- Apache MPM event
- Apache MPM netware
- Apache MPM os2
- Apache MPM prefork
- Apache MPM winnt
- Apache MPM worker
- Apache模塊 mod_actions
- Apache模塊 mod_alias
- Apache模塊 mod_asis
- Apache模塊 mod_auth_basic
- Apache模塊 mod_auth_digest
- Apache模塊 mod_authn_alias
- Apache模塊 mod_authn_anon
- Apache模塊 mod_authn_dbd
- Apache模塊 mod_authn_dbm
- Apache模塊 mod_authn_default
- Apache模塊 mod_authn_file
- Apache模塊 mod_authnz_ldap
- Apache模塊 mod_authz_dbm
- Apache模塊 mod_authz_default
- Apache模塊 mod_authz_groupfile
- Apache模塊 mod_authz_host
- Apache模塊 mod_authz_owner
- Apache模塊 mod_authz_user
- Apache模塊 mod_autoindex
- Apache模塊 mod_cache
- Apache模塊 mod_cern_meta
- Apache模塊 mod_cgi
- Apache模塊 mod_cgid
- Apache模塊 mod_charset_lite
- Apache模塊 mod_dav
- Apache模塊 mod_dav_fs
- Apache模塊 mod_dav_lock
- Apache模塊 mod_dbd
- Apache模塊 mod_deflate
- Apache模塊 mod_dir
- Apache模塊 mod_disk_cache
- Apache模塊 mod_dumpio
- Apache模塊 mod_echo
- Apache模塊 mod_env
- Apache模塊 mod_example
- Apache模塊 mod_expires
- Apache模塊 mod_ext_filter
- Apache模塊 mod_file_cache
- Apache模塊 mod_filter
- Apache模塊 mod_headers
- Apache模塊 mod_ident
- Apache模塊 mod_imagemap
- Apache模塊 mod_include
- Apache模塊 mod_info
- Apache模塊 mod_isapi
- Apache模塊 mod_ldap
- Apache模塊 mod_log_config
- Apache模塊 mod_log_forensic
- Apache模塊 mod_logio
- Apache模塊 mod_mem_cache
- Apache模塊 mod_mime
- Apache模塊 mod_mime_magic
- Apache模塊 mod_negotiation
- Apache模塊 mod_nw_ssl
- Apache模塊 mod_proxy
- Apache模塊 mod_proxy_ajp
- Apache模塊 mod_proxy_balancer
- Apache模塊 mod_proxy_connect
- Apache模塊 mod_proxy_ftp
- Apache模塊 mod_proxy_http
- Apache模塊 mod_rewrite
- Apache模塊 mod_setenvif
- Apache模塊 mod_so
- Apache模塊 mod_speling
- Apache模塊 mod_ssl
- Apache模塊 mod_status
- Apache模塊 mod_suexec
- Apache模塊 mod_unique_id
- Apache模塊 mod_userdir
- Apache模塊 mod_usertrack
- Apache模塊 mod_version
- Apache模塊 mod_vhost_alias
- Developer Documentation for Apache 2.0
- Apache 1.3 API notes
- Debugging Memory Allocation in APR
- Documenting Apache 2.0
- Apache 2.0 Hook Functions
- Converting Modules from Apache 1.3 to Apache 2.0
- Request Processing in Apache 2.0
- How filters work in Apache 2.0
- Apache 2.0 Thread Safety Issues
- 詞匯和索引
- 詞匯表
- 指令索引
- 指令速查
- 模塊索引
- 站點導航