模板引擎(Web开发中)
是为了使 用户界面 和 业务数据(内容)分离而产生的,它可以生成特定格式的文档,
利用模板引擎来生成前端的HTML代码,模板引擎会提供一套生成HTML代码的程序,之后只需获取用户的数据,放入渲染函数,该数据便会嵌入生成好的HTML页面中
,然后反馈给浏览器,呈现在用户面前
当前的主流框架,一般都采用MVC模式,即: Model-View-Controller
,用户的输入先进入Controller控制器,然后根据清流类型和请求的指令发送给对应的Model业务模型,由Model层进行业务逻辑的判断、数据库的存取等,最后把结果返回给View视图层,再经模板引擎的渲染展示给用户
模板引擎的基本机理就是 替换(转换) : 将指定的标签转换为需要的业务数据;将指定的伪语句按照某种流程来变换输出
引用一段代码来简单说一下:
// 模板
var template = '<p>Hello,my name is <%name%>.I am <%age%> years old.</p>';
// 用于匹配的正则
/*
用于过滤出以<%开头,%>结尾,并且中间不包含%或>的匹配项
其目的在于过滤出template中的 <%name%> 和 <%age%>
*/
var regex = /<%([^%]+)?%>/g;
// 数据
var data =
{
name:'Deutsh',
age:22
}
// 模板引擎
var TemplateEngine = function (template,data)
{
// exec使用全局正则表达式意味着在循环中使用,因为它仍然会检索所有匹配的子表达式
// /regex/.exec()仅返回找到的第一个匹配项
while (match = regex.exec(template))
{
template = template.replace(match[0],data[match[1]])
}
return template;
}
// 最终的执行在此处
var string = TemplateEngine(template,data)
console.log(string)
上述代码,我们的目的是:将 数据文件 中对应的name和age替换到 模板文件 中
主要的执行在模板引擎的while函数中,match = regex.exec(template)
会返回一个array
,这个数组中包含了连个项目
⚠️ 为什么会包含两项呢:当正则表达式设置 g
标志位时,可以多次执行 exec
方法来查找同一个字符串中的成功匹配
之后template = template.replace(match[0],data[match[1]])
等同于template = template.replace("<%name%>",data["name"])
完成模板中数据的替换
SSTI(模板注入)Server-Side Template Injection
由前面模板代码安利的演示,我们可以发现,
若服务端接受了用户的输入后(比如对于上述案例,data的name和age的数据由数据的输入/提交/请求而得),未经任何处理就将其作为Web应用模板内容的一部分
,就会导致模板引擎在进行目标编译渲染的过程中,执行了用户插入的可执行语句,从而可能导致信息泄露、代码执行等问题
凡是使用模板的地方,SSTI是绕不过的问题,模板引擎可由多种语言实现,所以SSTI也就出现在了多种语言环境中
模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎。
常见的模板引擎
- PHP
Twig
模板变量: {
{%s}}