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

树莓派温度展示项目中Fetch API解析JSON遇语法错误求助

问题

我正在开发一个低依赖JavaScript项目,用于展示树莓派的温度。服务端响应GET请求返回JSON数据,客户端通过网页展示该数据。已通过浏览器和Postman验证服务端工作正常,但客户端使用Fetch API时,两种JSON解析方式均出现语法错误,而调用公开JSON数据源却能正常工作。已尝试以下方案:

  • 两种不同的JSON解析方式
  • 使用不同的JSON数据源

期望实现服务端JSON的正确获取与解析。

服务端代码

const { spawn } = require("child_process");
const http = require('http');

http.createServer((req, res) => {
    if (req.url === '/') {
        res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
        const temp = spawn('cat', ['/sys/class/thermal/thermal_zone0/temp']);
        temp.stdout.on('data', function (data) {
            data = data / 1000;
            console.log('Temperature: ' + data + '°C');
            res.end(JSON.stringify({"temp":data}));
        });
        temp.stderr.on('data', function (data) {
            res.end(JSON.stringify({"temp":"Unavailable"}));
        });
    }
    else {
        res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify({"temp":"Unavailable"}));
    }
}).listen((process.argv[2] || 64567), () => {
    console.log('Server listening on http://localhost:' + (process.argv[2] || 64567));
});

客户端代码

<body>
    <script defer>
        await fetch('http://localhost:64567',{mode: 'no-cors'}).then(res => JSON.parse(res)).then(temp => document.getElementById("value").innerHTML = temp.temp);
        // SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data


        /*
        await fetch('http://localhost:64567',{mode: 'no-cors'}).then(res => res.json()).then(temp => document.getElementById("value").innerHTML = temp.temp)
        // SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

        await fetch('https://api.npoint.io/d5a7160bab77dd869b82').then(res => res.json()).then(temp => document.getElementById("value").innerHTML = temp.temp)
        // This one works
        */
    </script>
    <h3>Temperature:<span id="value"> </span> °C</h3>
</body>
解决方案

核心问题是你在fetch请求中添加的{mode: 'no-cors'},这个设置会让浏览器强制限制对响应内容的访问权限——哪怕服务端返回了正确的JSON,客户端也无法读取和解析。

1. 移除no-cors模式

修改客户端fetch调用,去掉限制模式,同时修正错误的解析方式:

await fetch('http://localhost:64567')
  .then(res => res.json())
  .then(temp => document.getElementById("value").innerHTML = temp.temp)
  .catch(err => console.error('请求失败:', err));

注意:你第一个写法里JSON.parse(res)是错误的,res是Response对象而非字符串,必须用res.json()来完成解析,这也是第一个报错的直接原因。

2. 处理跨域问题(若客户端与服务端不同源)

如果你的客户端网页是从其他端口/域名打开的(比如用Live Server运行在5500端口),需要在服务端添加CORS响应头,避免跨域报错:

// 在服务端的res.writeHead中添加CORS头
res.writeHead(200, { 
  'Content-Type': 'application/json; charset=utf-8',
  'Access-Control-Allow-Origin': '*' // 生产环境建议指定具体域名,而非通配符
});

3. 优化服务端数据读取逻辑

spawn的stdout的data事件可能触发多次(虽然读取温度文件概率极低),建议监听close事件确保数据完整:

let tempData = '';
const temp = spawn('cat', ['/sys/class/thermal/thermal_zone0/temp']);
temp.stdout.on('data', function (data) {
  tempData += data;
});
temp.on('close', function () {
  const tempValue = parseFloat(tempData) / 1000;
  console.log('Temperature: ' + tempValue + '°C');
  res.end(JSON.stringify({"temp": tempValue}));
});
temp.stderr.on('data', function () {
  res.end(JSON.stringify({"temp":"Unavailable"}));
});

内容的提问来源于stack exchange,提问作者user9541267

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:05:43