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

Node.js后端无法向React.js返回温度数据,报错res.send is not a function

问题原因
  • 变量名冲突:你的http.get回调函数里用了res作为参数,这和外层Express路由处理函数的res(Express响应对象)重名了,导致你在res.on("end")里调用的res其实是HTTP请求的响应对象,不是Express用来返回给前端的响应对象,所以会报错res.send is not a function(即使你用的是res.end,本质也是这个变量覆盖问题)。
修复方案

1. 修改变量名解决冲突

把http.get回调里的res改成其他名称(比如httpRes),这样就能正确引用外层的Express响应对象:

app.get("/gettemperature", (req, res) => {
    const email = req.query.email;

    let stmt = `SELECT * FROM users WHERE email=?`;
    let todo = [email];
    
    db.query(stmt, todo, (err, results, fields) => {
      if (err) {
        console.error(err.message);
        // 错误时返回响应,避免前端挂起
        return res.status(500).json({ error: err.message });
      }
      
      if(results.length === 0 ){
          return res.status(404).json({ error: "用户不存在" });
      }
      
      let id = results[0].id;
      let getID = `SELECT * FROM controlModules WHERE deviceowner=?`;
      let getidData = [id];

      db.query(getID, getidData, (err, resulta, fields) => {
        if (err) {
          console.error(err.message);
          return res.status(500).json({ error: err.message });
        }

        if(resulta.length === 0){
            return res.status(404).json({ error: "未找到对应设备" });
        }
        
        let lanip = resulta[0].ipaddress;
        let url = "http://"+lanip+"/data";

        // 将参数改为httpRes,避免和外层res冲突
        http.get(url,(httpRes) => {
            let body = "";
    
            httpRes.on("data", (chunk) => {
                body += chunk;
            });
    
            httpRes.on("end", () => {
                try {
                  let json = JSON.parse(body);
                  const temp_actual = json.temperature.value;
                  console.log(temp_actual);
                  
                  // 这里的res是外层的Express响应对象,可正常返回数据
                  res.json({ value: temp_actual });
                } catch (error) {
                    console.error(error.message);
                    return res.status(500).json({ error: "解析温度数据失败" });
                };
            });
    
        }).on("error", (error) => {
            console.error(error.message);
            return res.status(500).json({ error: "获取设备温度数据失败" });
        });
      });
    });
});

2. 用async/await简化代码(避免回调地狱)

如果你的Node.js版本支持,可将回调逻辑改为async/await,代码更清晰,也能减少变量冲突风险:

// 先把数据库查询和HTTP请求包装成Promise
const queryPromise = (sql, params) => {
  return new Promise((resolve, reject) => {
    db.query(sql, params, (err, results) => {
      if (err) reject(err);
      else resolve(results);
    });
  });
};

const httpGetPromise = (url) => {
  return new Promise((resolve, reject) => {
    http.get(url, (res) => {
      let body = "";
      res.on("data", chunk => body += chunk);
      res.on("end", () => resolve(body));
    }).on("error", reject);
  });
};

app.get("/gettemperature", async (req, res) => {
  try {
    const email = req.query.email;
    const userResults = await queryPromise(`SELECT * FROM users WHERE email=?`, [email]);
    
    if (userResults.length === 0) {
      return res.status(404).json({ error: "用户不存在" });
    }
    
    const id = userResults[0].id;
    const deviceResults = await queryPromise(`SELECT * FROM controlModules WHERE deviceowner=?`, [id]);
    
    if (deviceResults.length === 0) {
      return res.status(404).json({ error: "未找到对应设备" });
    }
    
    const lanip = deviceResults[0].ipaddress;
    const url = `http://${lanip}/data`;
    const body = await httpGetPromise(url);
    const json = JSON.parse(body);
    const temp_actual = json.temperature.value;
    
    // Express的res.json方法自动设置Content-Type并序列化JSON
    res.json({ value: temp_actual });
  } catch (err) {
    console.error(err.message);
    res.status(500).json({ error: err.message });
  }
});
关键注意事项
  • 所有错误分支必须返回响应,否则前端会一直处于等待状态直到超时;
  • 使用res.json()可以替代手动设置Content-Type和JSON.stringify,Express会自动处理这些细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 08:40:30