如何在.ejs文件中运行存储在数据库中的自定义代码字符串
实现方案
步骤1:后端预编译数据库存储的EJS代码
你存储在数据库中的字符串包含EJS语法,默认不会被EJS模板自动解析,需要先在服务端调用EJS的渲染方法完成预编译,再传入视图上下文。
以Express框架为例,代码示例:
const ejs = require('ejs'); // 全局路由中间件处理逻辑 app.use(async (req, res, next) => { // 1. 从数据库读取存储的snippet代码 const snippetCodeFromDB = await SiteSettings.findOne({ key: 'snippet_pixel' }).value; // 2. 预编译EJS语法,传入所有需要用到的变量 const renderedSnippet = ejs.render(snippetCodeFromDB, { settings: req.app.locals.settings, // 你的全局站点配置对象 order: req.order || {}, // 订单页传入订单对象,其他页面传空对象避免报错 // 其他snippet中用到的变量都在此处传入 }); // 3. 挂载到全局视图变量,所有页面都能直接读取,不需要每个路由单独传参 res.locals.renderedSnippet = renderedSnippet; next(); });
如果你不需要所有页面都加载该snippet,也可以只在对应路由的处理逻辑中执行上述预编译操作,单独传入视图上下文。
步骤2:公共头部partial中插入代码
因为预编译后的内容已经是可直接执行的HTML/JS代码,需要用EJS的非转义输出语法<%- %>,避免特殊字符被转义成纯文本。
在你的公共头部partial(比如views/partials/header.ejs)中需要插入snippet的位置添加如下代码即可:
<%- renderedSnippet %>
注意事项
- 权限控制:该snippet支持插入任意JS代码,仅开放给可信的管理人员编辑,避免出现XSS注入风险
- 异常兼容:如果snippet中用到了仅部分页面存在的变量(比如订单对象),要么在snippet代码中加存在性判断,要么预编译时给变量传入默认空值,避免渲染报错
- 性能优化:如果snippet内容不常更新,可以将预编译后的结果做缓存,snippet变更时再清除缓存重新编译,减少服务端计算开销
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

