无论何种语言、何种框架、何种web服务器,在实现HTTP服务的时候,都遵循“客户端请求服务器,服务器返回响应”的流程。静态网站直接返回静态资源,而动态网站在返回动态内容时,最终返回给客户端的仍然是渲染出来的HTML代码(或者相应mime type的资源),因为究其本质,终究是HTTP通信。
因为返回HTML是最终目的,所以除了写一个动态网站之外,还可以在服务器上以其它任何方式生成静态页面,实现相同的“动态”需求。
需求1:查看服务器指定目录中的内容
方法一,web服务器开启目录浏览功能
因为该功能将会暴露服务器目录,所以一般的web服务器都默认关闭,而打开的时候,也建议只针对路径来打开,而非全站开启。此处以nginx为例,在指定层级(可以是server,可以是location)开启autoindex on即可打开目录浏览功能,在浏览器访问对应地址将会实时展现对应目录的内容。
location /soft {
#如果请求的资源是一个目录,则在最后补上斜杠
if (-d $request_filename){
rewrite ^/(.*)([^/])$ https://$host/$1$2/ permanent;
}
alias /var/www/soft;
autoindex on;
#自动选择合适的文件体积单位,非必需配置
autoindex_exact_size off;
}
方法二,HTML文件生成
上文讲过,web客户端只对预定的mime类型感兴趣,服务器返回网页时,可以用任何方式将HTML代码作为响应内容返回给浏览器(并不限于浏览器,应该说web client更恰当),或者在服务端程序内部,或者在web服务器外部(比如,使用Shell)。
#!/bin/bash
htmlfile=/var/www/soft/soft2.html
echo '<html><head><title>soft</title></head><body>Last updated: ' > $htmlfile
echo `TZ=Asia/Shanghai date '+%Y-%m-%d %H:%M:%S %z'` >> $htmlfile
echo '<pre>' >> $htmlfile
ls -ahlF /var/www/soft >> $htmlfile
echo '</pre></html>' >> $htmlfile
这个脚本会创建一个HTML文件,内容是 /var/www/soft目录的枚举。将这个脚本添加到crontab每分钟执行一次,这样就可以保证每分钟都会重新生成一次,达到每分钟刷新一次的目的。
需求2:查看服务器的CPU、内存、硬盘状态
#!/bin/bash
htmlfile=/var/www/soft/soft2.html
echo '<html><head><title>soft</title></head><body>Last updated: ' > $htmlfile
echo `TZ=Asia/Shanghai date '+%Y-%m-%d %H:%M:%S %z'` >> $htmlfile
echo '<pre>' >> $htmlfile
top -bn1 | head -n 5 >> $htmlfile
echo >> $htmlfile
df -h >> $htmlfile
echo >> $htmlfile
/usr/sbin/smartctl -iH /dev/sda
echo '</pre></html>' >> $htmlfile
与需求一中的步骤一样,区别只在于生成HTML的脚本内容,最终效果如下
看到crontab的时候,有的人肯定已经看出其中一个很大的问题,这种方式时效太低,相比起动态语言实现的网站,它不能返回实时内容。
如果一定要返回实时内容,可以将crontab中的任务设置为每分钟运行,将脚本中的内容重复60次,每次完成后sleep一秒,甚至还可以不用crontab而是用死循环来跑任务。但这又带来一个性能浪费问题——无论有没有客户端请求,后台一直在做生成页面的动作,有点类似极低时间间隔的无脑轮询,如果运行的任务正好又需要耗费较大的系统资源,成本将变得不可接受(动态网站只有接收到用户请求的时候才会执行指定任务并返回结果,这种请求-响应模式,以及异步处理能力是本文所说的方法完全无法胜任的)。
基于以上原因,它的使用范围注定了极为有限(当然也并非一无是处),比如日备任务完成后,生成一个包含了备份目录的目录详情以及备份结果的HTML文件;又或者每天凌晨对服务器进行健康检查,将检查结果放到HTML文件里……这些都是合适的应用场景。