当前位置: 首页 > news >正文

【Nginx36】Nginx学习:SSI静态文件服务器端包含模块

Nginx学习:SSI静态文件服务器端包含模块

这个模块让我想到了 2009 年刚刚工作的时候。最早我是做 .NET 的,而第一家公司其实是从 ASP 向 ASP.NET 转型中,因此,还是有不少的 ASP 做的页面。在那个时候,就用到了 SSI 。

这么一说,大家估计也猜到了,这个功能其实是很早的技术了。现在的年轻大佬们可能很多都不知道这个功能。它可以让静态文件,也就是 HTML 文件实现一些简单的文件包含、定义变量、条件判断之类的功能。

这个模块的名称是 ngx_http_ssi_module 模块,它是一个过滤器,用于处理通过它的响应中的 SSI(服务器端包含)命令。目前,支持的 SSI 命令列表不完整。

SSI 模块的指令都可以在 http、server、location 下进行配置。SSI 模块是默认添加的模块,直接就可以使用。我们先来看看它的配置指令。这些配置不是今天的重点,今天的是重点是演示一下如何使用 SSI 。

ssi

启用或禁用响应中 SSI 命令的处理。

ssi on | off;

默认值是 off 。要使用 SSI 当然要把这个打开啦。

ssi_last_modified

允许在 SSI 处理期间保留原始响应中的“Last-Modified”标头字段,以促进响应缓存。

ssi_last_modified on | off;

默认值是 off 。默认情况下,当响应的内容在处理过程中被修改时,标头字段会被删除,并且可能包含动态生成的元素或部分,这些元素或部分会独立于原始响应而更改。

ssi_min_file_chunk

设置存储在磁盘上的响应部分的最小大小,从这里开始使用 sendfile 发送它们是有意义的。

ssi_min_file_chunk size;

默认值是 1k 。

ssi_silent_errors

如果启用,则在 SSI 处理期间发生错误时抑制“[an error occurred while processing the directive]”字符串的输出。

ssi_silent_errors on | off;

默认值是 off 。

ssi_types

除了“text/html”之外,还可以处理具有指定 MIME 类型的响应中的 SSI 命令。

ssi_types mime-type ...;

默认值是 text/html 。特殊值“*”匹配任何 MIME 类型 (0.8.29)。

ssi_value_length

设置 SSI 命令中参数值的最大长度。

ssi_value_length length;

默认值是 256 。

变量

  • $date_local 本地时区的当前时间。格式由带有 timefmt 参数的 config 命令设置。

  • $date_gmt 格林威治标准时间的当前时间。格式由带有 timefmt 参数的 config 命令设置。

SSI 语法

对于上面配置指令和变量的内容咱们就不多说了,直接配置一个服务器来学习 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;}
}

非常简单,就是监听了 8036 端口,然后定义了一个 /ssi/ 目录,然后再打开 ssi 功能。因为我们还会用到 PHP ,所以也加上了一个 PHP 的 FastCGI 配置。然后我们去 html 目录下创建一个  ssi 目录,在这个目录下面创建一个 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 中的注释,但是在注释中添加了一个 # 符号作为开始符号。接着就是命令以及命令相关的参数 。上面代码中,我们使用 include 命令加载文件,使用 set 定义变量,使用 echo 输出变量。使用 if 命令进行逻辑判断,最后的 block 命令是定义一个块,如果 include 加载的文件不存在时,就使用一个 stub 参数指定一个 block 显示 block 里面的内容。

接下来,准备最上面两个 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 参数 ,然后再把这个 title 参数打印出来。

好了,咱们访问一下这个页面试下吧。

➜  ~ 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 ,在错误日志文件中可以看到相应的错误信息。

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 又不能动态接收参数,其实呀,使用 PHP 套上静态页面就可以接收参数了嘛。还是先准备一个 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;
}

然后,准备一个 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!

返回的结果和我们 if 条件的预期一样。不过需要注意的是,这里的 if 判断条件没有大于、小于,只有等于、不等于、空或非空判断,但判断值可以是正则表达式。

总结

有意思吧,哈哈,早期的我们就是靠这个,实现 ASP 开发中头文件和脚文件的拆分的。不过现在真的很少见到了,毕竟一是纯静态网站已经很少了,二是各种语言框架都已经自带这些功能了。即使是做文章站那种生成纯静态页面的,也是直接去生成整张页面,和这个嵌套也没啥关系。

因此,它的应用场景现在确实很有限了。大家了解一下就好,特别是各位年轻的大佬,如果没见过的话,自己试试,其实也挺好玩的。

参考文档:

http://nginx.org/en/docs/http/ngx_http_ssi_module.html

相关文章:

【Nginx36】Nginx学习:SSI静态文件服务器端包含模块

Nginx学习&#xff1a;SSI静态文件服务器端包含模块 这个模块让我想到了 2009 年刚刚工作的时候。最早我是做 .NET 的&#xff0c;而第一家公司其实是从 ASP 向 ASP.NET 转型中&#xff0c;因此&#xff0c;还是有不少的 ASP 做的页面。在那个时候&#xff0c;就用到了 SSI 。 …...

StripedFly恶意软件框架感染了100万台Windows和Linux主机

导语 近日&#xff0c;一款名为StripedFly的恶意软件框架在网络安全研究人员的监视之外悄然感染了超过100万台Windows和Linux系统。这款跨平台的恶意软件平台在过去的五年中一直未被察觉。在去年&#xff0c;卡巴斯基实验室发现了这个恶意框架的真实本质&#xff0c;并发现其活…...

蓝桥杯每日一题2023.10.25

乘积尾零 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 由于需要相乘的数很多&#xff0c;所以我们不能直接进行暴力模拟&#xff0c;我们知道10 2 * 5&#xff0c; 所以我们只需要找出这个数2和5的个数&#xff0c;其中2和5个数小的那个则为末尾0出现的个数 #include<bi…...

【C++】详解map和set基本接口及使用

文章目录 一、关联式容器与键值对1.1关联式容器&#xff08;之前学的都是序列容器&#xff09;1.2键值对pairmake_pair函数&#xff08;map在插入的时候会很方便&#xff09; 1.3树形结构的关联式容器 二、set2.1set的基本介绍2.1默认构造、迭代器区间构造、拷贝构造&#xff0…...

如何学习 Linux 内核内存管理

Linux内核内存管理部分是Linux内核中第二复杂的部分&#xff0c;但也非常有趣。学习它的最佳方法就是阅读代码。但在不了解术语和当前 mm 部分到底发生了什么的情况下&#xff0c;显然不能随意开始阅读代码。因此&#xff0c;我想这样开始学习比较好&#xff1a; 了解当前的 LS…...

【计算机网络】(谢希仁第八版)第一章课后习题答案

1.计算机网络可以向用户提供哪些服务&#xff1f; 答&#xff1a;例如音频&#xff0c;视频&#xff0c;游戏等&#xff0c;但本质是提供连通性和共享这两个功能。 连通性&#xff1a;计算机网络使上网用户之间可以交换信息&#xff0c;好像这些用户的计算机都可以彼此直接连…...

Operator开发之operator-sdk入门

1 operator-sdk 除了kubebuilder&#xff0c;operator-sdk是另一个常用的用于开发Operator的框架&#xff0c;不过operator-sdk还是基于kubebuilder&#xff0c;因此&#xff0c;通常还是建议使用kubebuilder开发Operator。 2 环境准备 跟kubebuilder类似&#xff0c;需要安…...

RabbitMQ生产者的可靠性

目录 MQ使用时会出现的问题 生产者的可靠性 1、生产者重连 2、生产者确认 3、数据持久化 交换机持久化 队列持久化 消息持久化 LazyQueue懒加载 MQ使用时会出现的问题 发送消息时丢失&#xff1a; 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生…...

集群节点批量执行 shell 命令

1、SSH 工具本身支持多窗口 比如 MobaXterm&#xff1a; 2、编写脚本通过 ssh 在多台机器批量执行shell命令 创建 ssh_hosts 配置文件&#xff0c;定义需要批量执行的节点&#xff08;必须能够通过 ssh 免密登录&#xff0c;且存在同名用户&#xff09; vim ssh_hostsbig…...

fl studio21.2水果软件怎么设置中文?

FL Studio编曲软件真的是个神器&#xff0c;不过一开始打开看到全是英文&#xff0c;有点头大&#xff0c;对吧&#xff1f;其实切换成中文版超级简单&#xff0c;只需要几个步骤就搞定啦&#xff01;我自己也是用中文版的&#xff0c;觉得用起来更得心应手&#xff0c;效率也提…...

.NET CORE 3.1 集成JWT鉴权和授权2

JWT&#xff1a;全称是JSON Web Token是目前最流行的跨域身份验证、分布式登录、单点登录等解决方案。 通俗地来讲&#xff0c;JWT是能代表用户身份的令牌&#xff0c;可以使用JWT令牌在api接口中校验用户的身份以确认用户是否有访问api的权限。 授权&#xff1a;这是使用JWT的…...

nbcio-boot如何进行gitee第三方登录

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 1、用户g…...

【C语言】字符函数、字符串函数与内存函数

简单不先于复杂&#xff0c;而是在复杂之后。 目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1 介绍 1.1.2 strlen 函数模拟实现 1.1.2.1 计数器方法 1.1.2.2 递归方法 1.1.2.3 指针 - 指针方法 1.2 strcpy 1.2.1 介绍 1.2.2 strcpy 函数模拟实现 1.3 strcat 1…...

生成树协议:监控 STP 端口和交换机

什么是生成树协议 生成树协议 &#xff08;STP&#xff09; 用于网络交换机&#xff0c;以防止循环和广播风暴。在局域网 &#xff08;LAN&#xff09; 中&#xff0c;两条或多条冗余路径可以连接到同一网段。当交换机或网桥从所有可用端口传输帧时&#xff0c;这些帧开始在网…...

【黑产攻防道03】利用JS参数更新检测黑产的协议破解

任何业务在运营一段时间之后都会面临黑产大量的破解。验证码和各种爬虫的关系就像猫和老鼠一样, 会永远持续地进行博弈。极验根据十一年和黑产博弈对抗的经验&#xff0c;将黑产的破解方式分为三类&#xff1a; 1.通过识别出验证码图片答案实现批量破解验证&#xff0c;即图片…...

什么是web3.0?

Web 3.0&#xff0c;也常被称为下一代互联网&#xff0c;代表着互联网的下一个重大演变。尽管关于Web 3.0的确切定义尚无共识&#xff0c;但它通常被认为是一种更分散、更开放且更智能的互联网。 以下是Web 3.0的一些主要特征和概念&#xff1a; 1. 去中心化 Web 3.0旨在减少…...

二、W5100S/W5500+RP2040树莓派Pico<DHCP>

文章目录 1 前言2 简介2 .1 什么是DHCP&#xff1f;2.2 为什么要使用DHCP&#xff1f;2.3 DHCP工作原理2.4 DHCP应用场景 3 WIZnet以太网芯片4 DHCP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 …...

【开源】基于SpringBoot的天然气工程业务管理系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…...

讯飞星火大模型V3.0 WebApi使用

讯飞星火大模型V3.0 WebApi使用 文档说明&#xff1a;星火认知大模型Web文档 | 讯飞开放平台文档中心 (xfyun.cn) 实现效果 初始化 首先构建一个基础脚手架项目 npm init vuelatest用到如下依赖 "dependencies": {"crypto-js": "^4.2.0",&q…...

拥有DOM力量的你究竟可以干什么

如果你希望访问 HTML 页面中的任何元素&#xff0c;那么您总是从访问 document 对象开始&#xff01; 查找HTML元素 document.getElementById(id) 通过元素 id 来查找元素 <!DOCTYPE html> <html> <head><meta charset…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

RabbitMQ 各类交换机

为什么要用交换机&#xff1f; 交换机用来路由消息。如果直发队列&#xff0c;这个消息就被处理消失了&#xff0c;那别的队列也需要这个消息怎么办&#xff1f;那就要用到交换机 交换机类型 1&#xff0c;fanout&#xff1a;广播 特点 广播所有消息​​&#xff1a;将消息…...

智能体革命:企业如何构建自主决策的AI代理?

OpenAI智能代理构建实用指南详解 随着大型语言模型&#xff08;LLM&#xff09;在推理、多模态理解和工具调用能力上的进步&#xff0c;智能代理&#xff08;Agents&#xff09;成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同&#xff0c;智能代理能够自主执行工…...