node vm 虚拟机模板
2021年11月24日案例1
1 2 3 4 5 6 7 |
const vm = require('vm') const user = {name: 'haha'} const template = '`<h2>${user.name}</h2>`' const explanTemplate = vm.runInNewContext(template, {user}) console.log(const) |
案例2 加上xss过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
const vm = require('vm') const user = {name: 'haha', js: '<script>alert("111")</script>'} const template = '`<h2>${user.name}</h2>${_(user.js)}`' const explanTemplate = vm.runInNewContext(template, { user, _: function (markup) { if (!markup) return ''; return String(markup) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/'/g, ''') .replace(/"/g, '"') } }) console.log(explanTemplate) |
案例3 加上 include
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
const vm = require('vm'); const templateMap = { templateA: '`<h2>${include("templateB")}</h2>`', templateB: '`<p>hahahaha</p>`' } const helper = { include(name) { return templateMap[name]() }, _: function (markup) { if (!markup) return ''; return String(markup) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/'/g, ''') .replace(/"/g, '"') } } Object.keys(templateMap).forEach(key => { const temp = templateMap[key]; templateMap[key] = vm.runInNewContext(` (function() {return ${temp}}) `, helper); }) console.log(templateMap['templateA']()); |
案例4 加上 include 可以加变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
const fs = require('fs'); const vm = require('vm'); const templateCache = {}; // 创建模板渲染context const templateContext = vm.createContext({ include: function (name, data) { const template = templateCache[name] || createTemplate(name) return template(data); } }); /** * * @param {*} templatePath 模板路径 * @returns 渲染好的html字符串 */ function createTemplate(templatePath) { templateCache[templatePath] = vm.runInContext( `(function (data) { with (data) { return `${fs.readFileSync(templatePath, 'utf-8')}` } })`, templateContext ); return templateCache[templatePath] } module.exports = createTemplate |