武漢做網(wǎng)站的公司有哪些比較好友情鏈接也稱為
Nginx學(xué)習(xí):SSI靜態(tài)文件服務(wù)器端包含模塊
這個模塊讓我想到了 2009 年剛剛工作的時候。最早我是做 .NET 的,而第一家公司其實是從 ASP 向 ASP.NET 轉(zhuǎn)型中,因此,還是有不少的 ASP 做的頁面。在那個時候,就用到了 SSI 。
這么一說,大家估計也猜到了,這個功能其實是很早的技術(shù)了。現(xiàn)在的年輕大佬們可能很多都不知道這個功能。它可以讓靜態(tài)文件,也就是 HTML 文件實現(xiàn)一些簡單的文件包含、定義變量、條件判斷之類的功能。
這個模塊的名稱是 ngx_http_ssi_module 模塊,它是一個過濾器,用于處理通過它的響應(yīng)中的 SSI(服務(wù)器端包含)命令。目前,支持的 SSI 命令列表不完整。
SSI 模塊的指令都可以在 http、server、location 下進行配置。SSI 模塊是默認(rèn)添加的模塊,直接就可以使用。我們先來看看它的配置指令。這些配置不是今天的重點,今天的是重點是演示一下如何使用 SSI 。
ssi
啟用或禁用響應(yīng)中 SSI 命令的處理。
ssi on | off;
默認(rèn)值是 off 。要使用 SSI 當(dāng)然要把這個打開啦。
ssi_last_modified
允許在 SSI 處理期間保留原始響應(yīng)中的“Last-Modified”標(biāo)頭字段,以促進響應(yīng)緩存。
ssi_last_modified on | off;
默認(rèn)值是 off 。默認(rèn)情況下,當(dāng)響應(yīng)的內(nèi)容在處理過程中被修改時,標(biāo)頭字段會被刪除,并且可能包含動態(tài)生成的元素或部分,這些元素或部分會獨立于原始響應(yīng)而更改。
ssi_min_file_chunk
設(shè)置存儲在磁盤上的響應(yīng)部分的最小大小,從這里開始使用 sendfile 發(fā)送它們是有意義的。
ssi_min_file_chunk size;
默認(rèn)值是 1k 。
ssi_silent_errors
如果啟用,則在 SSI 處理期間發(fā)生錯誤時抑制“[an error occurred while processing the directive]”字符串的輸出。
ssi_silent_errors?on?|?off;
默認(rèn)值是 off 。
ssi_types
除了“text/html”之外,還可以處理具有指定 MIME 類型的響應(yīng)中的 SSI 命令。
ssi_types mime-type ...;
默認(rèn)值是 text/html 。特殊值“*”匹配任何 MIME 類型 (0.8.29)。
ssi_value_length
設(shè)置 SSI 命令中參數(shù)值的最大長度。
ssi_value_length length;
默認(rèn)值是 256 。
變量
$date_local
本地時區(qū)的當(dāng)前時間。格式由帶有 timefmt 參數(shù)的 config 命令設(shè)置。$date_gmt
格林威治標(biāo)準(zhǔn)時間的當(dāng)前時間。格式由帶有 timefmt 參數(shù)的 config 命令設(shè)置。
SSI 語法
對于上面配置指令和變量的內(nèi)容咱們就不多說了,直接配置一個服務(wù)器來學(xué)習(xí) SSI 的使用吧。
server{listen 8036;root html;location /ssi/ {ssi on;}location ~ \.php$ {root html;fastcgi_pass unix:/var/sock/php-fpm/www.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;}
}
非常簡單,就是監(jiān)聽了 8036 端口,然后定義了一個 /ssi/ 目錄,然后再打開 ssi 功能。因為我們還會用到 PHP ,所以也加上了一個 PHP 的 FastCGI 配置。然后我們?nèi)?html 目錄下創(chuàng)建一個 ?ssi 目錄,在這個目錄下面創(chuàng)建一個 index.html 文件。
<!--#?include?file="header.html"?-->
<!--#?include?file="/ssi/header.php?title=testssi"?--><!--#?set?var="name"?value="zyblog"?-->
<!--#?set?var="age"?value="37"?--><!--#?echo?var="name"?-->
<!--#?echo?var="age"?-->
<!--#?echo?var="id"?default="123456"?--><!--#?if?expr="$age?=?37"?-->
37
<!--#?elif?expr="$age?!=?40"?-->
young
<!--#?else?-->
old
<!--#?endif?--><!--#?block?name="one"?-->
this?is?block?one.<br/>
<!--#?endblock?-->
<!--#?include?virtual="/ssi/abc.html"?stub="one"?-->
<!--#?include?file="/ssi/123.html"?stub="one"?-->
看出來這個 SSI 的語法了吧。
<!--#?command?parameter1=value1?parameter2=value2?...?-->
它直接使用 HTML 中的注釋,但是在注釋中添加了一個 # 符號作為開始符號。接著就是命令以及命令相關(guān)的參數(shù) 。上面代碼中,我們使用 include 命令加載文件,使用 set 定義變量,使用 echo 輸出變量。使用 if 命令進行邏輯判斷,最后的 block 命令是定義一個塊,如果 include 加載的文件不存在時,就使用一個 stub 參數(shù)指定一個 block 顯示 block 里面的內(nèi)容。
接下來,準(zhǔn)備最上面兩個 include 需要加載的文件。
<!--?header.html?-->
this?is?header.html!<br/>
header.html 就是顯示一句話。
<?php
//?header.php
$title?=?$_GET['title'];
?>
title?is?'<?php?echo?$title;?>'!<br/>
header.php 文件里面則是接收一個 title 參數(shù) ,然后再把這個 title 參數(shù)打印出來。
好了,咱們訪問一下這個頁面試下吧。
???~?curl?http://192.168.56.88:8036/ssi/
this?is?header.html!<br/>title?is?'testssi'!<br/>zyblog
37
12345637this?is?block?one.<br/>this?is?block?one.<br/>
中間的空行我故意沒有去掉,從這里可以看出,SSI 的命令行以及 PHP 代碼在解析完成之后是會變成空行的。最下面的兩個使用 block 的 include ,在錯誤日志文件中可以看到相應(yīng)的錯誤信息。
2022/09/21?23:20:28?[error]?1513#0:?*38?open()?"/usr/local/nginx/html/ssi/abc.html"?failed?(2:?No?such?file?or?directory),?client:?192.168.56.1,?server:?,?request:?"GET?/ssi/index.html?HTTP/1.1",?subrequest:?"/ssi/abc.html",?host:?"192.168.56.88:8036",?referrer:?"http://xxx"
2022/09/21?23:20:28?[error]?1513#0:?*38?open()?"/usr/local/nginx/html/ssi/123.html"?failed?(2:?No?such?file?or?directory),?client:?192.168.56.1,?server:?,?request:?"GET?/ssi/index.html?HTTP/1.1",?subrequest:?"/ssi/123.html",?host:?"192.168.56.88:8036",?referrer:?"http://xxx"
上面例子中,if 判斷貌似沒啥用呀,畢竟我們的變量是寫死的。然后 SSI 又不能動態(tài)接收參數(shù),其實呀,使用 PHP 套上靜態(tài)頁面就可以接收參數(shù)了嘛。還是先準(zhǔn)備一個 lcoation 來進行測試。
location ^~ /ssiphp/ {alias html/ssi/;fastcgi_pass unix:/var/sock/php-fpm/www.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $request_filename;include fastcgi_params;ssi on;
}
然后,準(zhǔn)備一個 if.php 文件。
<?php
$age?=?$_GET['age'];
?>
<!--#?set?var="age"?value="<?php?echo?$age;?>"?-->
<!--#?if?expr="$age?=?37"?-->
37
<!--#?elif?expr="$age?!=?40"?-->
not?40
<!--#?else?-->
old?or?young??old!
<!--#?endif?-->
測試一下吧,看看 if 的效果怎么樣。
???~?curl?"http://192.168.56.88:8036/ssiphp/if.php?age=37"37???~?curl?"http://192.168.56.88:8036/ssiphp/if.php?age=49"not?40???~?curl?"http://192.168.56.88:8036/ssiphp/if.php?age=40"old?or?young??old!
返回的結(jié)果和我們 if 條件的預(yù)期一樣。不過需要注意的是,這里的 if 判斷條件沒有大于、小于,只有等于、不等于、空或非空判斷,但判斷值可以是正則表達式。
總結(jié)
有意思吧,哈哈,早期的我們就是靠這個,實現(xiàn) ASP 開發(fā)中頭文件和腳文件的拆分的。不過現(xiàn)在真的很少見到了,畢竟一是純靜態(tài)網(wǎng)站已經(jīng)很少了,二是各種語言框架都已經(jīng)自帶這些功能了。即使是做文章站那種生成純靜態(tài)頁面的,也是直接去生成整張頁面,和這個嵌套也沒啥關(guān)系。
因此,它的應(yīng)用場景現(xiàn)在確實很有限了。大家了解一下就好,特別是各位年輕的大佬,如果沒見過的話,自己試試,其實也挺好玩的。
參考文檔:
http://nginx.org/en/docs/http/ngx_http_ssi_module.html