本文參照的系統環境:
l Windows XP SP2
l Apache HTTP Server v2.0.55 (Win32)
什麼是 SSI?
SSI(Server Side Includes),是嵌套在 HTML 網頁中的指示語句,由後台服務器進行代碼的解釋計算。使用 SSI 可以動態的創建一部分網頁內容而不需要編寫複雜的 JSP/ASP/PHP 等程序。SSI 是如此的小巧以至於不應算作一門語言,因為他遠沒有JSP/ASP/PHP 等程序那麼複雜,只有一些極其有限的語法規則。但就算是只有這有限的一點語法規則,只要開動起你創新的思維,仍然可以「小才大用」,為你帶來效率的提高、體力的節省和腦力的放鬆 J
很多 HTTP Server 程序都支持 SSI,可能語法稍有不同,比如: IIS/Novell HTTP Server 等等,大同小異,本文要說明的是 Apache 2.0 的 SSI。閒話少說,我想告訴大家的是,這是一篇實踐經驗總結性的文章,後文中的示例解決方案都是來自實際的網站應用中。其中的一些想法和概念會給你帶來提示性的參考或者直接拿為所用。
下圖展示了 SSI 被服務器解釋,生成最終的純 HTML 網頁後,再發送給訪問者瀏覽的過程:
系統環境安裝
這不是一篇教你如何配置 Apache 的文章,但為了在你在本地系統環境測試的方便,還是簡單的說明一下。
首先可以到 http://www.apache.org/ 網站去下載一份最新的 Apache 安裝文件,安裝之後是否要做其他設置請自行參考相關資料,這裡只說明如何開啟 SSI 支持的步驟。
我在本地創建了一個 bnn 的文件夾,設成虛擬目錄,然後就可以通過瀏覽器訪問:http://localhost/bnn/
打開 Apache 的配置文件,例如:C:\Program Files\Apache Group\Apache2\conf\httpd.conf
然後加入類似下面的這段代碼(主要是中間的三行):黑體字部分是文件夾路徑。
|
<Directory “D:/Works/Jan-Boy/bnn“> AddType text/html .ssi Options Includes AddOutputFilterByType INCLUDES;DEFLATE text/html </Directory> |
OK,「Restart」Apache Server (如果右下角系統欄中有 apache 小圖標,則左鍵點擊選擇 Restart; 也可以在「開始 -> 程序」菜單的 Apache 項下面找到 Restart 命令; 還可以直接在安裝目錄運行C:\Program Files\Apache Group\Apache2\bin \ApacheMonitor.exe 後點擊 Restart 按鈕)。
測試 SSI 是否已經打開,在 bnn 文件夾下面新建一個 index.html 文件,打開後在裡面寫上:
|
<!–#echo var=”DATE_LOCAL” –> |
保存關閉,然後打開瀏覽器測試:http://localhost/bnn/
如果正確的顯示出類似「Wednesday, 01-Mar-2006 02:03:06 China Standard Time」這樣的文字就表示 SSI 開啟成功!
「呼~~」深呼一口氣,搞掂,收工!
開始 SSI
參考資源
在正式開始之前,先介紹兩個官方參考文檔:
Apache Tutorial: Introduction to Server Side Includes
http://httpd.apache.org/docs/2.0/howto/ssi.html
Apache Module mod_include
http://httpd.apache.org/docs/2.0/mod/mod_include.html
這些文檔在 Apache 的安裝文件夾中可以找到,然後通過 HTTP 進行訪問,並提供多國語言版本,不過沒有中文(已經習慣了,誰讓CN常常是被忽視的小弱國呢~,不過似乎網上流傳了英雄好漢們翻譯過的部分內容)。
在官方網站上可以找到最新版的文檔(包括更新測試版的文檔):http://httpd.apache.org/docs-project/
SSI 語法
SSI 指令的語法格式:
|
<!–#element attribute=value attribute=value … –> |
舉幾個實際例子:
|
http://<!–#echo var=」SERVER_NAME」 var=」DOCUMENT_URI」 –> <!–#include virtual=」ssi/footer.ssi」 –> <!–#set var=」Protocol」 value=」http」 –> |
SSI 語句是直接嵌套在 HTML 頁面中的,可以放置在任意的位置。所以 SSI 語句前後採用 HTML 註釋的寫法,這樣一旦服務器關閉了對 SSI 的支持,此時訪問頁面的話,也不會直接在網頁上顯示出不必要的代碼。
參見語法格式圖示:
圖 2
注意:
1. 在結尾符號「–>」的前面需要有一個空格,是不能丟掉的,曾經在一個複雜的頁面中遇到一個問題是因為沒有加上那個空格引起的,因為很多時候容易忽略到這個小問題,而往往最難糾錯的就是這些小問題引起。
2. SSI 不區分大小寫,包括元素名稱、變量名稱,大寫和小寫都是允許的。
良好的書寫格式可以幫助你更好的調試代碼,清晰易查找,特別是在寫非常複雜的 SSI 的時候,因為沒有軟件工具可以自動對 SSI 語句進行排版(因為大多數工具會把 SSI 語句當作普通的 HTML 註釋處理,Dreamweaver 只能識別 include 元素的 SSI 指令語句),所以就需要在書寫的時候自己整理代碼,養成良好習慣,注意大小寫和上下文的縮進關係等。
書寫格式的約定(推薦格式,並非強制):
l 元素和屬性使用小寫字母;
l 環境變量都使用大寫字母;
l 合理的縮進,在使用 if 語句嵌套的時候推薦使用 1 tab(占 4 space) 縮進,以變更清晰的顯示層次關係。
SSI 使用
對於 SSI 具體的使用是否有些不清楚呢?下面列出一份完整的示例代碼:
|
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml”> <head> <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ /> <title>Learning Apache SSI</title> <link href=”includes/style.css” rel=”stylesheet” type=”text/css” /> </head> <body> <!–#include virtual=”/bnn/ssi/header.ssi”–> <div id=”Main”> <div id=”LeftNav”>Left Navigation</div> <div id=”RightNav”>Right Navigation</div> <div id=”Content”> <p>This is “<a href=”http://<!–#echo var=’SERVER_NAME’ –>“>Learning Apache SSI</a>” testing page!</p> <p>Hello SSI</p> <p>Today is: <!–#echo var=”DATE_LOCAL” –></p> </div> </div> <!–#include virtual=”ssi/footer.ssi”–> </body> </html> |
說明:
1. SSI 可以插入在網頁的任意地方;
2. 屬性值要合理使用雙引號和單引號,例如「<!–#echo var=’SERVER_NAME’ –>」這個位置,大多數情況下, SERVER_NAME 使用雙引號不會出現問題,但在一些複雜的網頁裡面仍然會造成歧義,Apache 無法識別正確的引號配對匹配。
變量和數據類型
SSI 中的變量分為自定義變量和環境變量。
自定義變量使用 set 命令來創建:
|
<!–#set var=」Protocol」 value=」http」 –> |
說明:var 屬性值就是變量名稱;value 的屬性值就是變量值。上面的語句表示,創建了一個 「Protocol」的變量,變量所代表的值是 「http」。
環境變量是系統已經存在的一些默認的變量和變量值,可以直接使用。例如:
|
<!–#echo var=」DATE_LOCAL」 –> |
說明: DATE_LOCAL 就是一個環境變量,用來顯示當前本地時間。類似的環境變量還有很多,比如常用HTTP_HOST、SERVER_NAME、DOCUMENT_URI、DOCUMENT_NAME 等等。
想知道到底有多少個可以用的環境變量麼?很簡單的方法:
|
<!–#printenv –> |
說明:printenv 命令就是這個作用,將所有的環境變量和變量當前值列表出來。我們把上面的一行代碼放入到任意一個頁面中,然後通過瀏覽器訪問這個頁面:
圖 3
看到的很亂頁面,查看源代碼吧:
哦,原來是一個純文本格式的,每行第一個等號前面的是環境變量名稱,後面就是他所代表的字符串值。
|
HTTP_ACCEPT=*/* HTTP_ACCEPT_LANGUAGE=en-us,zh-cn;q=0.5 HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 1.1.4322) HTTP_HOST=localhost HTTP_CONNECTION=Keep-Alive HTTP_COOKIE=dbx-postmeta=grabit=2+,5+,6-,1-,4-,3-,0-&advancedstuff=0-,1-,2- PATH=C:\Program Files\ThinkPad\Utilities;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\IBM\Infoprint Select;C:\Program Files\ATI Technologies\ATI Control Panel;C:\Program Files\QuickTime\QTSystem\;C:\Program Files\ThinkPad\ConnectUtilities SystemRoot=C:\WINDOWS COMSPEC=C:\WINDOWS\system32\cmd.exe PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH WINDIR=C:\WINDOWS SERVER_SIGNATURE=<address>Apache/2.0.55 (Win32) PHP/5.1.1 Server at SERVER_SOFTWARE=Apache/2.0.55 (Win32) PHP/5.1.1 SERVER_NAME=localhost SERVER_ADDR=127.0.0.1 SERVER_PORT=80 REMOTE_ADDR=127.0.0.1 DOCUMENT_ROOT=D:/Works/Jan-Boy SERVER_ADMIN=admin@boynannan.com SCRIPT_FILENAME=D:/Works/Jan-Boy/bnn/printenv.html REMOTE_PORT=2529 GATEWAY_INTERFACE=CGI/1.1 SERVER_PROTOCOL=HTTP/1.0 REQUEST_METHOD=GET QUERY_STRING= REQUEST_URI=/bnn/printenv.html SCRIPT_NAME=/bnn/printenv.html DATE_LOCAL=Thursday, 02-Mar-2006 11:15:45 DATE_GMT=Thursday, 02-Mar-2006 03:15:45 GMT LAST_MODIFIED=Wednesday, 01-Mar-2006 10:02:13 DOCUMENT_URI=/bnn/printenv.html USER_NAME=<unknown> DOCUMENT_NAME=printenv.html |
數據類型:SSI 中只有一種數據類型「字符串」。例如:
|
<!–#set var=」MyFirstVar」 value=」120」 –> <!–#set var=」MySecondVar」 value=」20」 –> |
說明:上面的語句表示 MyFirstVar 變量代表的值是字符串 「120」,而不是數字 120;MySecondVar 等於字符串「20」。這樣,如果對這兩個變量進行大小比較,MySecondVar 要大於 MyFirstVar,因為字符串之間的大小比較是從左到右逐個字符比較,每個字符比較按照字符在 ASCII 碼的先後順序,後面的大於前面的;例如上面的例子,「2」大於「1」所以字符串「20」大於「120」。
SSI 常用元素
SSI 的元素並不多,下面列出常用的元素和屬性,其它請查看官方參考。
echo
作用:將變量值寫入 HTML 代碼中。
屬性:
l var – 值是變量名稱
示例:
|
<!–#echo var=」DATE_LOCAL」 –> http://<!–#echo var=」SERVER_NAME」 var=」DOCUMENT_URI」 –> |
說明:
1. echo 元素允許同時有多個 var 屬性,這樣在輸出的時候會將這兩部分字符串連起來。
2. var 後面的屬性值就是變量名稱。
include
作用:將另一個文件的內容寫入語句所在的頁面。include 是 SSI 中最常用的命令,也是 SSI 主要功能的體現。
屬性:
l virtual – 被包含文件的路徑
示例:
|
<!–#include virtual=”ssi/header.ssi”–> <!–#include virtual=”/cgi-bin/ap/optin_cn.pl?btn=send&fax=yes” –> |
說明:
1. 值不不可以包含主機名,只能是一個路徑;
2. 路徑可以是相對當前文件(SSI 語句所在的頁面)或者從「/」開始,相對網站根目錄的路徑;
3. 路徑後允許加參數,比如:「/cgi-bin/ap/optin_cn.pl?btn=send&fax=yes」,這句表示:/cgi-bin/ap/optin_cn.pl 是具體的 perl 腳本執行文件,?btn=send&fax=yes 是參數,參數是從在文件名後接一個問號開始,後面如果有多個參數,每個參數之間使用 & 號連接。示例語句包括了 2個參數btn=send 和fax=yes。參數傳遞給腳本文件執行後生成 HTML 代碼,再返回到 SSI 語句所在的頁面。
4. SSI 是允許嵌套的;例如,假設有三個文件,文件1 include 文件2,文件2中 include 文件3。
set
作用:設置(創建/修改)變量和變量值
屬性:
l var – 變量名
l value – 變量值
示例:
|
<!–#set var=」Protocol」 value=」http」 –> |
說明:
1. 變量值都是字符串類型
2. 如果要給一個變量值設為「」IBM」」(注意,IBM 前後有英文字符的雙引號),有兩種方法:
方法一:<!–#set var=”MyVar” value=’”IBM”‘ –>
方法二:<!–#set var=”MyVar” value=”\”IBM\”" –>
引號是特殊字符,如果直接寫在代碼中會出現歧異,比如寫成 <!–#set var=”MyVar” value=”"IBM”" –> 後,服務器並不能判斷到底哪兩個雙引號是配對的匹配。所以就要避免這種寫法;方法一,外面用單引號,裡面用雙引號,這樣引號配對問題就解決了,很方便。方法二,使用了轉義字符來避免這個問題。反斜槓(\)是轉義字符,將特殊字符轉換成原本的字符含義。
3. 如何讓一個變量值等於另一個變量值?請看示例:
結果是,MyVar2 和 MyVar1 的變量值相同;就是說要在 SSI 語句中引用一個變量,使用 $ 符號後面加上變量名。
|
<!–#set var=」MyVar1」 value=」IBM」 –> <!–#set var=」MyVar2」 value=」$MyVar1」 –> <!–#echo var=」MyVar2」 –> |
4. 繼續上個例子,假設有 3個變量,第三個變量值是前兩個變量值相連:
參看下面的例子,很清晰,為了正確表示一個變量名,我們使用大括號把變量名稱括起來,例如:${MyVar1} 。
|
<!–#set var=」MyVar1」 value=」IBM」 –> <!–#set var=」MyVar2」 value=」Services」 –> <!–#set var=」MyVar3」 value=」${MyVar1}${MyVar1}」 –> <!–#echo var=」MyVar3」 –> <br /> <!–#set var=」MyVar3」 value=」abc${MyVar1}_${MyVar1}def」 –> <!–#echo var=」MyVar3」 –> |
5. 仍然繼續這個例子,要在頁面上顯示 $IBM 該如何寫呢?
使用轉義字符「\」反斜槓。
|
<!–#set var=」MyVar1」 value=」IBM」 –> <!–#set var=」MyVar2」 value=」\$MyVar1」 –> <!–#echo var=」MyVar2」 –> |
6. 另一個把變量寫在 SSI 語句中的例子:
<!–#include virtual=”/servers/eserver/${cc}/ssi/nav_left.ssi” –>
fsize 和flastmod
作用:顯示指定文件的大小(fsize)和指定文件的最後修改時間(flastmod)
屬性:
l virtual – 與元素 include 中的屬性相同,不同的是:<!–#fsize virtual=」/cgi-bin/cmail.pl」 –> 結果返回的是這個 Perl 腳本文件的大小,而不是運行這段 Perl 腳本的結果。
SSI 配置元素
config
作用:配置一些 SSI 運行結果;錯誤信息、文件大小格式、時間格式。
屬性:
l errmsg – 當 SSI 語句運行出錯時顯示的信息。
例如:<!–#config errmsg=”出錯啦~~” –>
l sizefmt – 顯示以何種方式顯示文件大小。這個屬性有兩個值:bytes 和 abbrev。
例如:<!–#config sizefmt=”abbrev” –>
u bytes:按照bytes 大小顯示;
u abbrev:按照 bytes、Kb 或者 Mb 動態顯示。
l timefmt – 顯示時間的格式。屬性值的參數同 C 標準庫中的strftime(3) 相同;參看其他的時間格式符:
http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
這裡有篇中文說明:http://cn.php.net/manual/zh/print/function.strftime.php
例如:<!–#config timefmt=”%Y-%m-%d”–>
示例:
|
<!–#config timefmt=”%Y-%m-%d”–> <meta name=”DC.DATE” scheme=”iso8610″ content=”<!–#echo var=』LAST_MODIFIED』–>”> |
說明:上例中是個實際的例子,這樣在每次編輯頁面後,不再需要手動更改 DC.DATE 的 meta 了。
其他配置
SSI 語句中的 前置符 和 後置符, 錯誤提示,時間顯示格式等等 也可以在 Apache 的配置文件中進行配置。具體的說明參看:
http://httpd.apache.org/docs/2.0/mod/mod_include.html
文中Directives 部分。
流控制元素
條件語句
SSI 中只有條件語句一種結構,而且結構很簡單。基本的控制元素:
|
<!–#if expr=”test_condition” –> Blablabla~~ <!–#elif expr=”test_condition” –> Blablabla~~ <!–#else –> Blablabla~~ <!–#endif –> |
說明:
l 如果(if 行)expr 屬性中的條件成立(為真)則執行下面語句部分(if 和 elif 之間,可以是 HTML 代碼,也可以是其他 任意 SSI 語句)。否則繼續 elif 中 expr 條件判斷,同樣。如果以上 2個條件均不成立則執行 else 和 endif 之間的部分代碼。
l elif 行可以有若干行;也可以沒有 elif。
l else 行根據實際情況也可以沒有。
l 第一行和最後一行必須存在。
l if 語句可以嵌套,你可以在 if 塊中再加入一個 if 塊語句。
操作符
上例中 test_condition 可以是以下情況:
l string – 如果只是非空字符,則返回 真,條件成立。
例如: <!–#if expr=”IBM” –> 表示條件成立;
<!–#if expr=”" –> 空字符,返回 假,條件不成立。
判斷一個變量是否為空字符串的一種寫法:<!–#if expr=”$MyVar = 『』” –>
l string1 = string2 – 兩個字符串相同則為真,不同則為假。
string1 != string2 – 兩個字符串不同則為真,相同則為假。
例如:如果變量 $DOCUMENT_URI 值等於 /bnn/index.html 則為真,否則不成立。
string2 也可以是正則表達式,將在下一節講述。
|
<!–#if expr=”$DOCUMENT_URI = 『/bnn/index.html』” –> Blablabla~~ <!–#endif –> |
l string1 < string2
string1 <= string2
string1 > string2
string1 >= string2
比較兩邊字符串,字符串之間的比較上文有描述,按照 ASCII 的順序比大小。請參看前文。
l ( test_condition ) – 如果test_condition 為真,則返回真,否則為假;
l ! test_condition – 如果test_condition 為真,則返回假,否則為真;
l test_condition1 && test_condition2 – (表示和關係)只有兩邊的 test_condition 都為真的時候才返回真;
l test_condition1 || test_condition2 – (表示或者關係)兩邊的 test_condition 只要有一個為真,則返回真。
「=」和「!=」的優先級要比「&&」和「||」高,「!」級別最高;因此下面的例子結果是相同的:
|
<!–#if expr=”$a = test1 && $b = test2″ –> <!–#if expr=”($a = test1) && ($b = test2)” –> |
&& 和 || 具有相同的優先級,可以使用括號 () 進行分組。
任何不被識別為變量或者操作符都被當作是一個字符串。字符串也可以使用引號(單引號或者雙引號)括起來。不被引號括起來的字符串中不允許有空格或者 Tab,因為空格是被用來起到分隔的作用。如果一個字符串中包含空格,請使用引號括起來。
例如:
|
<!–#if expr=”$a = test1 && $b = 『test 2』” –> |
正則表達式
Regular expression (正則表達式,縮寫 RE),是一種對字符串進行匹配查找的高效模式。幾乎每一種語言都支持 RE;Apache SSI 中的 RE 語法同 Perl(版本 5)語言中的相同,但並不完整的支持,似乎最新的 Apache 2.2 中才引入完整的 Perl RE(不足為信,尚未測試)。
此處並不詳細說講述 RE,只做簡單介紹,具體請參看 Perl RE 的官方文檔:
http://perldoc.perl.org/perlre.html
同時提供 PDF 離線版本下載:http://perldoc.perl.org/perlre.pdf
先看一個 SSI 中使用 RE 的例子:
|
<!–#if expr=”$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/” –> <!–#set var=”session” value=”$1″ –> <!–#endif –> |
說明:此例表示從參數中提取子字符串。$QUERY_STRING 是環境變量,表示通過網頁 URL 傳遞過來的參數,例如:
http://www.IBM.com/index.html?sid=safsaf43513sadfz&cntry=cn
其中,問號後面的部分就是 $QUERY_STRING 的值。
如果右邊的比較部分是 /~~/ 這種形式,則表示,這部分是正則表達式,斜槓 / 就是表達式的開始和結束。斜槓中間的部分是具體的表達式。
<!–#if expr=”$QUERY_STRING = /^sid=([a-zA-Z0-9]+)/” –>
這一行表示,如果 URL 參數中包含有 RE 所匹配的字符,則 if 語句成立,繼續執行此行下面的語句。
^sid=([a-zA-Z0-9]+)
^ 符號表示匹配字符串的開頭,就是說,要匹配的字符串必須是 「sid=」 開頭;括號表示分組,用圓括號分組的同時,程序自動會將圓括號內匹配的部分提取出來保存在 $1 這個變量中;這個 $1 是系統變量,用來保存正則表達式分組提取出來的各個部分值,一共有 9個,$1-$9。中括號 [] 表示裡面字符串中的任意一個或多個,a-z 表示 26個小寫字母,同理 A-Z,0-9 等。後面的 + 加號表示 + 前面的字符可以有 1個以上(至少有一個)。
http://www.IBM.com/index.html?sid=safsaf43513sadfz&cntry=cn
由此,這個例子中,匹配正則表達式的字符串是:「sid=safsaf43513sadfz」。& 號用來連接多個參數,因為 & 符號並沒有包含在 a-zA-Z0-9 的範圍內,所以 & 後面的字符串部分就不算匹配的部分。
<!–#set var=”session” value=”$1″ –>
此行表示設置一個變量 session,變量值為正則表達式中匹配的圓括號包含的部分字符,因此等於 「safsaf43513sadfz」。
我們可以用這種方法來出來傳過來的參數,而不需要其他後台程序的支持,簡單的需求,使用 SSI 就可以處理,既簡單又減少了服務器的負載。
|
<!–#include virtual=”ssi/comments.ssi?smoke=die” –> |
另外一個例子:
|
<!–#if expr=”$DOCUMENT_URI = /index.html/” –> |
很顯然,第一行要簡單得多;只要 URL 中包括了可以確定唯一的關鍵字 index.html,則 if 語句成立。
第二行原理和第一行相同,使用了正則表達式,但這種寫法的意思是因為 / 斜槓是特殊字符,所以需要使用 反斜槓 \ 來進行轉義(\ 是轉義字符)。其他的特殊字符請參看 RE 的參考文檔。但這種寫法顯然複雜了些,使用正則表達式就是為了簡單,所以在使用的時候,首先要考慮可以確定的唯一的關鍵字。比如 index.html – 同一個目錄下不可能相同名字的兩個文件。
第三行沒有使用正則表達式,而是用了字符串的比較,顯然這種方法也不是最佳,字符串之間要相等,必須左右兩邊完全相同才可以,如果 $DOCUMENT_URI 是一個很長的值,那這行代碼你也需要寫很長。
正則表達式的優 勢就在這裡,方便、簡短、高效!不過在入門開始寫的時候稍微有些麻煩,這是因為編寫複雜的正則表達式的時候,人們大腦的思維方式稍微和以往不同;因此就需 要多加練習。為了提高效率和節省時間,一些常用的正則表達式,我們也可以在網上找到,比如一些好的正則表達式庫網站,有很多示例和代碼可以參考使用。
Regular Expression Library:http://www.regxlib.com/
編寫正則表達式的工具軟件:(這裡只列了兩個,還有很多小工具幫你編寫正則表達式,Google 吧~~)
The Regex Coach:http://www.weitz.de/regex-coach/
The Regulator:http://royo.is-a-geek.com/iserializable/regulator/
解決方案
其實上面的一些小例子中已經出現過幾個常用的解決方案,比如:
l 自動寫 DC.DATE 的方法;
l SSI 的參數傳遞,並使用正則表達式對參數進行分析等。
接下來,再把我在實際應用中常見的幾個典型的 SSI 方案拿出來,僅供參考!
SSI 與 JavaScript
SSI 與 JS 如何一起使用呢?是這樣的,由於服務器並不能識別 JS 代碼,所以可以把 SSI 語句放到 JS 代碼行中,這樣取代一部分 JS 代碼的工作,將這部分工作放到服務器端運行。
|
<!–#if expr=”$DOCUMENT_URI = /\/bnn\//” –> <!–#set var=”LASLink” value=”http://localhost/bnn/” –> <!–#set var=”LASText” value=”Learning Apache SSI” –> <!–#endif –> <script type=”text/javascript”> //<![CDATA[ document.write(『<a class=”fbox” href=”<!–#echo var=”LASLink” –>“><!–#echo var=”LASText” –></a>』); //]]> </script> |
說明:如上例所示,SSI 語句可以寫在 JS 語句內部,在服務器端執行 SSI,然後將最終生成的完整 HTML 網頁代碼發送到瀏覽器,在瀏覽器中再繼續執行 JS 腳本。
由於有些功能使用 SSI 要比 JS 簡單,而且具有在服務器端先行運行的優勢。根據需要,事半功倍噢~~
SSI 與 日期
前幾天遇到這樣一個需求:一個 Promotion - 3月3日之前顯示默認的內容,3月3日之後顯示另外一個內容。下面給出這段代碼,分享一下類似這種的要求該如何入手。
|
<!–#config timefmt=”%Y-%m-%d”–> <!–#if expr=”$DATE_LOCAL = /(.+)-(.+)-(.+)/” –> <!–#if expr=”($2 = ‘03′) && ($3 != /0[1-3]/)” –> 3月3日之後 <!–#else –> 默認 <!–#endif –> <!–#endif –> |
說明:上面的例子只是拋磚引玉,如果時間跨度和日期要改變的話例子要做稍微的調整。首先說第一行,配置顯示日期的格式,然後第二行,使用正則表達式將月份和日期數據分組提取出來;裡面的又一個 if 嵌套語句判斷是否是 3月,並且不包括 1-3日(因為是 3月3日之後)。
頁面佈局
圖 3
拿這個典型的三欄式網頁作為例子,Header:頭部,Left Nav:左導航,Nav Trail:當前位置,Right Nav:右導航,Footer:尾部。
通常情況下,上面有 4個區域是不經常變動的:Header、Left Nav、Nav Trail 和 Footer。因此,使用 SSI 的 include 元素會是一個很好的解決方案。下面給出例子代碼事例:
|
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml”> <head> <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ /> <title>Learning Apache SSI</title> <link href=”includes/style.css” rel=”stylesheet” type=”text/css” /> </head> <body> <!–#include virtual=”ssi/header.ssi”–> <div id=”Main”> <div id=”LeftNav”><!–#include virtual=”ssi/nav_left.ssi”–></div> <div id=”RightNav”><!–#include virtual=”ssi/nav_right.ssi”–></div> <div id=”Content”> <div id=”NavTrail”><!–#include virtual=”ssi/nav_trail.ssi”–></div> <p>Hello SSI</p> </div> </div> <!–#include virtual=”ssi/footer.ssi”–> </body> </html> |
說明:上例中加粗體的部分是將整個網站頁面相同的部分取出來放到一個 SSI 文件中,這樣一旦需要整個網站需要調整,這些公共的區域將會很容易修改。
導航條
拿上個例子中的左導航做例子。
|
<!–#set var=”protocol” value=”" –> <!–#if expr=”$HTTPS = /ON/” –> <!–#set var=”protocol” value=”http://${SERVER_NAME}” –> <!–#endif –> <!–#set var=”protocols” value=”https://${SERVER_NAME}” –> <ul> <li class=”TopLink”><a class=”left-nav-overview” href=”<!–#echo var=’protocol’ –>/ “>IBM</a></li> <li class=”PrimaryLink<!–#if expr=’$DOCUMENT_URI = /\/systems\/cn\//’ –>-Highlight<!–#endif –>“><a class=”left-nav” href=”<!–#echo var=’protocol’ –>/systems/cn/”>Systems</a></li> <li class=”PrimaryLink<!–#if expr=’$DOCUMENT_URI = /\/contact\/index.html/’ –>-Highlight<!–#endif –>“><a class=”left-nav” href=”<!–#echo var=’protocols’ –>/contact/index.html”>聯繫我們</a></li> </ul> |
說明:這個例子看起來稍微有點複雜,下面分部分講述。
l 前 5行的用處是,為了避免 https 加密頁面的問題,如果你以 https://~~ 的加密方式打開一個頁面(通常是表單註冊頁面),則這個頁面的內容將會使用加密的方式在網絡上傳輸,增強了安全性。但打開這個頁面後,在這個頁面上還有其他的部需要加密的鏈接,如果沒有指定這些鏈接是以 http 協議進行傳輸,則默認情況下將會和 https 這個頁面的傳輸協議相同,使用 https 協議(這時候鼠標滑上頁面上的鏈接,然後查看狀態欄的提示,看到是 https://~~~ )。為避免這個問題產生,就加了這 5行代碼進行控制。
<!–#if expr=”$HTTPS = /ON/” –> 表示,如果 HTTPS 協議被打開($HTTPS 是環境變量),則執行 if 下面的語句。
l <!–#echo var=’protocol’ –> 表示,以 http 協議開始 URL;
l <!–#echo var=’protocols’ –> 表示,以 https 協議開始 URL;用在鏈到表單註冊頁的鏈接前(例子中,聯繫我們鏈接)。
l <!–#if expr=”$DOCUMENT_URI = /\/systems\/cn\//” –> 表示,這個鏈接塊何時高亮顯示。如果當前打開的頁面是 /systems/cn/ 下面的任意一個頁面,則這個鏈接塊將高亮顯示。
當前位置
Nav Trail 又叫做 Breadcrumb,中文裡我們叫做「當前位置」。在頁面上,根據當前頁面所在不同,在這個地方會有提示訪問者當前所在的位置。如果在每個頁面都存在這個提示的話,編輯起來會很麻煩。但現在可以使用 SSI 解決這個問題,只要在每個頁面的這個位置 include 一個 SSI 文件就可以了,當前所在位置的工作交給 SSI 來完成。
示例代碼:
|
<!–#set var=”protocol” value=”" –> <!–#if expr=”$HTTPS = /ON/” –> <!–#set var=”protocol” value=”http://${SERVER_NAME}” –> <!–#endif –> <!–#set var=”protocols” value=”https://${SERVER_NAME}” –> <!–#set var=”NavTrailLink1″ value=”" –> <!–#set var=”NavTrailLinkName1″ value=”" –> <!–#set var=”NavTrailLink2″ value=”" –> <!–#set var=”NavTrailLinkName2″ value=”" –> <!–#set var=”NavTrailLink3″ value=”" –> <!–#set var=”NavTrailLinkName3″ value=”" –> <!–#if expr=”$DOCUMENT_URI = /\/bnn\// && $DOCUMENT_URI != /\/bnn\/index.html/” –> <!–#set var=”NavTrailLink1″ value=”${protocol}/bnn/” –> <!–#set var=”NavTrailLinkName1″ value=”BNN” –> <!–#if expr=”$DOCUMENT_URI = /\/bnn\/books\// && $DOCUMENT_URI != /\/bnn\/books\/index.html/” –> <!–#set var=”NavTrailLink2″ value=”${protocol}/bnn/books/” –> <!–#set var=”NavTrailLinkName2″ value=”圖書館” –> <!–#elif expr=”$DOCUMENT_URI = /\/bnn\/food\// && $DOCUMENT_URI != /\/bnn\/food\/index.html/” –> <!–#set var=”NavTrailLink2″ value=”${protocol}/bnn/food/” –> <!–#set var=”NavTrailLinkName2″ value=”好吃的” –> <!–#if expr=”$DOCUMENT_URI = /\/bnn\/food\/strawberry\// && $DOCUMENT_URI != /\/bnn\/food\/strawberry\/index.html/” –> <!–#set var=”NavTrailLink3″ value=”${protocol}/bnn/food/strawberry/” –> <!–#set var=”NavTrailLinkName3″ value=”草莓” –> <!–#endif –> <!–#endif –> <!–#endif –> <img alt=”" class=”display-img” height=”6″ src=”//www.ibm.com/i/c.gif” width=”1″ /><!–#if expr=”$NavTrailLink1″ –><a class=”bctl” href=”<!–#echo var=’NavTrailLink1′ –>“><!–#echo var=”NavTrailLinkName1″ –></a><span class=”bct”> > </span><!–#if expr=”$NavTrailLink2″ –><a class=”bctl” href=”<!–#echo var=’NavTrailLink2′ –>“><!–#echo var=”NavTrailLinkName2″ –></a><span class=”bct”> > </span><!–#if expr=”$NavTrailLink3″ –><a class=”bctl” href=”<!–#echo var=’NavTrailLink3′ –>“><!–#echo var=”NavTrailLinkName3″ –></a><span class=”bct”> > </span><!–#endif –><!–#endif –><!–#endif –><br /> |
最後一個不做分析啦。
Written by 傻仔仔
