Node.js后端向express-handlebars传递JSON对象异常求助
解决Handlebars模板中脚本无法正确处理后端传递的JSON数据问题
我来帮你排查并解决这个问题——核心原因是Handlebars的自动转义机制以及你在模板脚本中处理数据的方式不对,咱们一步步来修复:
第一步:优化后端数据处理逻辑
你的后端代码里做了多余的JSON.parse再JSON.stringify操作,而且代码格式太紧凑不利于排查问题,先把它整理并简化:
exports.dashboard = function (req, res) { dashboardModel.findAll() .then(dasboards => { let monsterData = null; if (dasboards.length > 0) { console.log(dasboards[9].monster); // 直接解析数据库中的JSON字符串为JavaScript对象 try { monsterData = JSON.parse(dasboards[9].monster); console.log(JSON.stringify(monsterData)); } catch (parseErr) { console.error('Failed to parse monster JSON:', parseErr); monsterData = []; } } else { console.log('no dashboard'); } // 将原始数据和解析后的monster对象一起传给模板 res.render('dashboard', { dasboard: dasboards, monsterData: monsterData }); }) .catch(dbErr => { // 新增数据库查询错误处理,避免服务崩溃 console.error('Error fetching dashboard data:', dbErr); res.status(500).send('Server Error'); }); };
这里做了几个关键优化:
- 新增
try-catch处理JSON解析失败的情况,避免因为数据库中存储的JSON格式错误导致服务异常 - 代码格式化,可读性更强
- 直接把解析后的JavaScript对象传给模板,不需要额外序列化
第二步:修正前端模板的脚本处理逻辑
你之前在脚本里用var j="{{{ js}}}"的方式是错误的——因为{{{ }}}虽然能避免转义,但如果传递的是对象,Handlebars会调用它的toString()方法,得到的是[object Object]这类无效的JSON格式,自然无法解析。
正确的做法是在模板中直接用JSON.stringify把后端传来的对象转成合法的JSON字符串,再用三重花括号输出,这样脚本里直接就能拿到可用的对象:
<script type="text/javascript"> // 直接将后端传来的monsterData对象序列化为JSON并输出,三重花括号避免转义 const monsterData = {{{ JSON.stringify(monsterData) }}}; // 现在monsterData已经是一个完整的JavaScript对象,不需要再JSON.parse console.log(monsterData[0]?.fileName); // 用可选链避免数组索引越界报错 console.log(monsterData[0]?.fileLink); </script>
为什么之前的写法会出问题?
- HTML中直接显示
{{this.monster}}正常,是因为浏览器会自动把Handlebars转义后的"渲染成正常的双引号,所以视觉上没问题,但本质上是转义后的字符串; - 而在脚本中,转义后的字符串(比如
[{"fileName":...}])无法被JSON.parse正确解析,因为"不是合法的JSON引号; - 三重花括号
{{{ }}}确实能关闭自动转义,但如果传递的是对象,Handlebars会把它转成[object Object]的字符串,同样无法解析。
另一种备选方案(直接传递JSON字符串)
如果你更倾向于后端直接传递序列化好的JSON字符串,也可以这么做:
后端修改:
// 在res.render时传递序列化后的字符串 res.render('dashboard', { dasboard: dasboards, monsterJson: JSON.stringify(monsterData) });
前端脚本修改:
<script type="text/javascript"> // 用三重花括号输出未转义的JSON字符串,再用JSON.parse解析 const monsterData = JSON.parse('{{{ monsterJson }}}'); console.log(monsterData[0].fileName); </script>
这样也能达到同样的效果,看你个人习惯选择就行。
内容的提问来源于stack exchange,提问作者Saurav Mir
相关产品推荐
相关产品推荐

