You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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转义后的&quot;渲染成正常的双引号,所以视觉上没问题,但本质上是转义后的字符串;
  • 而在脚本中,转义后的字符串(比如[{&quot;fileName&quot;:...}])无法被JSON.parse正确解析,因为&quot;不是合法的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:57:56