Fetch返回数据console可正常打印但插入script标签显示[object Object]
问题描述
我正在尝试在客户端从自有服务器获取JSON数据,之后将其插入到<script>标签中,代码如下:
<script> const bodyTag = document.getElementsByTagName("body")[0]; const url = "https://ourAPI.com"; const parameters = { method: "GET", headers: new Headers(), mode: "cors", cache: "default", }; fetch(url, parameters).then((response) => { if (response.ok) { response.json().then((data) => { console.log(data.imports); // 这里能正常打印获取到的数据 const importmap = document.createElement("script"); importmap.type = "systemjs-importmap"; importmap.innerHTML = data.imports; // 这里赋值后标签里显示"[object Object]" bodyTag.appendChild(importmap); }); } }); </script>
执行console.log(data.imports)时可以正常展示获取到的数据,但最终生成的<script>标签内容如下:
<script type="systemjs-importmap">[object Object]</script>
测试发现:当使用JSON.stringify(data)处理数据时,script标签内可以正常展示从API获取的完整字符串格式数据,但直接赋值JSON对象时无法正常提取内容。
<script type="systemjs-importmap"> ...完整字符串格式数据... </script>
错误原因
这是典型的类型不匹配问题:
- DOM元素的
innerHTML属性只接受字符串类型的值,直接传入JavaScript对象时,浏览器会自动调用对象的toString()方法做隐式类型转换,普通普通对象调用toString()的固定返回值就是"[object Object]",和你看到的异常内容完全一致。 console.log能正常展示对象内容,是浏览器控制台做了专门的结构化对象渲染,和DOM赋值的字符串转换逻辑没有关系。- 另外
systemjs-importmap类型的script标签本身规范就要求内部填充合法的JSON文本,本身就不支持直接传入JS对象,你之前测试JSON.stringify可以正常生效,本质就是刚好符合了该标签的内容格式要求。
修正方法
只需要把要插入的对象序列化为合法JSON字符串再赋值即可,修正后的核心代码如下:
fetch(url, parameters).then((response) => { if (response.ok) { response.json().then((data) => { const importmap = document.createElement("script"); importmap.type = "systemjs-importmap"; // 序列化对象为JSON字符串,第三个参数为缩进空格数,方便调试查看 importmap.textContent = JSON.stringify({ imports: data.imports }, null, 2); bodyTag.appendChild(importmap); }); } });
额外优化点:
- 优先使用
textContent代替innerHTML给script标签赋值纯文本,减少不必要的HTML解析开销,同时规避特殊字符意外转义的问题 - 如果接口返回的
data本身就是{ imports: {...} }的完整importmap结构,直接JSON.stringify(data)即可,不需要额外嵌套包裹imports字段
内容的提问来源于stack exchange,提问作者Fabio Matsumoto
相关产品推荐
相关产品推荐

