Node.js中如何避免res.render()解析数组时生成'&quot'?
解决Node.js + Pug中res.render传递数组时引号被转义的问题
作为Node.js初学者碰到这种转义问题确实挺闹心的——你用res.render把数组传给Pug模板时,#{topics}会把引号转成",导致前端拿到的变量格式乱掉,没法正常使用对吧?先看看你的代码场景:
你的现有代码
- index.pug 中定义变量的代码:
script. var topics = #{topics}; - index.js 中处理数据并渲染模板的代码:
router.get('/', function(req, res) { var data = []; papers.getAllTopics(function(err, content) { if(err) { throw err; } else { for (var i = 0; i<content.length; i++){ data.push(content[i].TOPIC); } res.render('index', { topics: data }); } }); });
问题原因
Pug的#{}插值语法默认会对HTML特殊字符做转义处理,目的是防止XSS攻击,但这就导致数组转成JSON时的引号被转成了HTML实体,前端script标签里拿到的就不是正常的数组格式了,自然没法直接使用。
几种可行的解决方案
方案1:用!{}直接输出不转义的内容
把Pug里的#{topics}换成!{topics},这样Pug就不会对内容做转义,直接输出数组的原始JSON格式:
script. var topics = !{topics};
⚠️ 注意:如果你的topics数组里包含用户输入的内容,用这个方法会有XSS攻击风险,所以只适合数据完全可信的场景(比如从自己数据库读取的无用户输入的数据)。
方案2:后端转成JSON字符串,前端解析
在后端把数组转成JSON字符串,前端用JSON.parse()还原成数组,这种方式更安全:
- 修改
index.js的代码:router.get('/', function(req, res) { var data = []; papers.getAllTopics(function(err, content) { if(err) { throw err; } else { for (var i = 0; i<content.length; i++){ data.push(content[i].TOPIC); } // 把数组转成JSON字符串 const topicsJson = JSON.stringify(data); res.render('index', { topics: topicsJson }); } }); }); - 修改
index.pug的代码:script. var topics = JSON.parse(#{topics});
这种方式下,#{}转义后的JSON字符串能被JSON.parse正确解析,同时还能避免XSS风险,因为特殊字符已经被转义,前端解析后又会还原成原始数据。
方案3:用Pug内置的JSON处理
直接在模板里用JSON.stringify处理数组,再结合插值:
script. var topics = !{JSON.stringify(topics)};
和方案2原理类似,只是把JSON转换的步骤放到了模板里,同样要注意如果数据不可信的话,还是优先方案2或者做额外的XSS过滤。
总结
如果你的数据完全可信(没有用户输入的内容),方案1最直接;如果要考虑安全性,方案2是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Alex Emerton
相关产品推荐
相关产品推荐

