Node.js报错TypeError: res.setHeader is not a function求助
问题原因分析
错误核心是变量名冲突:
- 路由回调里的
res是Express框架的响应对象,具备setHeader、end等方法,用于向前端返回响应。 - 但你在
http.get(url,(res) => {处使用了同名参数res,覆盖了外层的Express响应对象。此时内层的res是Node.js原生http模块的响应对象,它没有setHeader方法,所以执行到标注位置时触发TypeError。 - VSCode提示的“res已声明但未被读取”,正是因为外层的Express
res被内层同名变量覆盖,实际未被使用。
修复方案
- 重命名内层http.get的响应参数,避免覆盖外层Express的响应对象,比如改成
httpRes。 - 修复SQL插入语句的占位符错误:原语句
INSERT INTO report(...) VALUES ()缺少占位符,需改为VALUES (?, ?, ?, ?, ?, ?),否则插入操作会失败。 - 完善错误处理:查询不到用户/设备、http请求失败等场景下,返回对应错误响应,避免请求长期挂起。
修改后的代码片段
app.get("/gettemperature", (req, res) => { const email = req.query.email; //step1 get device ip from database using let stmt = `SELECT * FROM users WHERE email=?`; let todo = [email]; console.log("email: "+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 userid = results[0].id; console.log(userid); let getID = `SELECT * FROM controlModules WHERE deviceowner=?`; let getidData = [userid]; db.query(getID, getidData, (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: "未找到该用户的设备"}); } const lanip = results[0].ipaddress; console.log(lanip); //step2 get temp where device ip //for local connection let url = "http://"+lanip+"/data"; // 重命名内层res为httpRes,避免覆盖外层Express的res http.get(url,(httpRes) => { let body = ""; httpRes.on("data", (chunk) => { body += chunk; }); httpRes.on("end", () => { try{ let json = JSON.parse(body); const temperature = json.temperature.value; const humidity = json.humidity.value; const waterlevel = ""; const nutrient = ""; console.log(temperature); let date_ob = new Date(); let date = ("0" + date_ob.getDate()).slice(-2); let month = ("0" + (date_ob.getMonth() + 1)).slice(-2); let year = date_ob.getFullYear(); let hours = date_ob.getHours(); let minutes = date_ob.getMinutes(); let seconds = date_ob.getSeconds(); const dateStamp = month+"/"+date+"/"+year+" "+hours+":"+minutes if(lanip != ""){ //getting parentid console.log(userid); // 修复SQL占位符错误 let inserreport = `INSERT INTO report(date,farm,temperature,humidty,waterlevel,nutrientsolutionlevel) VALUES (?, ?, ?, ?, ?, ?)`; let inserreportval = [dateStamp,userid,temperature,humidity,waterlevel,nutrient]; //inserting to childtable db.query(inserreport, inserreportval, (err, data, fields) => { if (err) { console.error(err.message); return res.status(500).json({error: err.message}); } //success inserting to table then get inserted data console.log(userid); let getreport = `SELECT * FROM report WHERE farm=?`; let getreportval = [userid]; console.log("getreportval "+getreportval); //getting report list db.query(getreport, getreportval, (err, results, fields) => { if (err) { console.error(err.message); return res.status(500).json({error: err.message}); } let data = []; for(let i = 0; i < results.length; i++){ data.push({ date: results[i].date, temperature: results[i].temperature, }); } // 现在使用的是外层的Express响应对象res,可正常调用方法 res.setHeader("Content-Type", "application/json"); res.writeHead(200); res.end(JSON.stringify(data,null,3)); }); }); } }catch(error) { console.error(error.message); return res.status(500).json({error: error.message}); }; }); }).on("error", (error) => { console.error(error.message); return res.status(500).json({error: "获取设备数据失败: " + error.message}); }); //end of step2 }); }); });
内容的提问来源于stack exchange,提问作者Ian Ducao
相关产品推荐
相关产品推荐

