Fastify传递参数异常:为何对象显示为[object Object]?
Fastify传递对象到HBS的script标签中显示为
[object Object]问题解析 问题场景
接手一个中断项目时,使用Fastify向HBS模板传递对象参数,发现参数在HTML标签中正常,但在<script>标签里被渲染成了[object Object]字符串,无法正常作为JS对象使用。
相关代码
index.js
/** * Our home page route * * Returns src/pages/index.hbs with data built into it */ fastify.get("/", function(request, reply) { const colors = require("./src/colors.json"); let params = { seo: seo, colors: colors }; reply.view("/src/pages/index.hbs", params); });
index.hbs
<form class="color-search" method="post"> <label for="sim"> <select name="sim" id="sim"> </select> </label> <label for="box"> <select name="box" id="box"> </select> </label> </form> <script> let box = $('select[name=box]'); let sim = $('select[name=sim]'); sim.append('<option>Choose one</option>'); console.log("test") console.log({{colors}}) $.each({{colors}}, function(key, entry) { sim.append($('<option></option>').attr('value', entry).text(entry.name)); }); </script>
colors.json
{ "Sim A": { "Box A": { "name": "", "connects": ["Box B"] }, "Box B": { "name": "", "connects": ["Box A", "Box C"] } }, "Sim B": { "Box C": { "name": "", "connects": ["Box B", "Box D"] }, "Box D": { "name": "", "connects": ["Box C", "Box E"] }, "Box E": { "name": "", "connects": ["Box D"] } } }
控制台渲染结果
let box = $('select[name=box]'); let sim = $('select[name=sim]'); sim.append('<option>Choose one</option>'); console.log("test") console.log([object Object]) // 问题所在 $.each([object Object], function(key, entry) { sim.append($('<option></option>').attr('value', entry).text(entry.name)); });
原因分析
HBS模板引擎在渲染变量时,若直接输出对象类型,会默认调用对象的toString()方法。而JS中普通对象的toString()返回值就是[object Object],所以在<script>标签里会被渲染成这个字符串,而非预期的JS对象字面量。
在HTML标签上下文里,模板引擎可能会有不同的处理逻辑,但在JS代码块中,必须确保输出的是合法的JS语法内容。
解决方案
需要将对象序列化为JSON字符串,再在JS中转为对象,或者直接输出为JS可识别的对象字面量,具体有两种方式:
方式一:使用JSON.stringify和JSON.parse
在HBS模板中,先用JSON.stringify将对象转为JSON字符串(注意用三个大括号{{{}}}避免HTML转义),再在JS中用JSON.parse解析:
<script> let box = $('select[name=box]'); let sim = $('select[name=sim]'); sim.append('<option>Choose one</option>'); console.log("test") const colors = JSON.parse('{{{JSON.stringify colors}}}'); console.log(colors) $.each(colors, function(key, entry) { sim.append($('<option></option>').attr('value', entry).text(entry.name)); }); </script>
方式二:直接输出对象字面量(推荐)
利用JSON.stringify输出的JSON字符串本身就是合法的JS对象字面量,直接赋值给变量:
<script> let box = $('select[name=box]'); let sim = $('select[name=sim]'); sim.append('<option>Choose one</option>'); console.log("test") const colors = {{{JSON.stringify colors}}}; console.log(colors) $.each(colors, function(key, entry) { sim.append($('<option></option>').attr('value', entry).text(entry.name)); }); </script>
注意:必须使用三个大括号{{{}}},因为HBS默认会把双引号转义为",导致JSON字符串失效,三个大括号会跳过HTML转义,输出原始的JSON内容。
内容的提问来源于stack exchange,提问作者Legacy Coding
相关产品推荐
相关产品推荐

