将API参数存入常量后Node.js应用崩溃,请求排查解决
问题
为何将API密钥、位置等参数存入常量后,我的Node.js应用会崩溃?若注释第一个拼接的const url,直接使用写死参数的URL则运行正常。
代码示例
app.get('/', function(req, res) { const query = "London"; const apiKey = "c3fd0e578a1e8ead729deb6f25"; const unit = "metric"; const url = "https://api.openweathermap.org/data/2.5/weather?q=" + query + "&appid=" + apiKey + "&units=" + unit; const url = "https://api.openweathermap.org/data/2.5/weather?q=London&appid=c3fd0e578a1e8ead729deb6f25d&units=metric" https.get(url, function(response) { console.log(response.statusCode); response.on("data", function(data) { const weatherData = JSON.parse(data); const temp = weatherData.main.temp; const weatherDescription = weatherData.weather[0].description; const icon = weatherData.weather[0].icon; const iconURL = "http://openweathermap.org/img/wn/" + icon + "@2x.png"; res.set("Content-Type", "text/html"); res.write("<h1>The temperature in London is " + temp + "C</h1>"); res.write("<p>The weather is currencly " + weatherDescription + "</p>"); res.write("<img src=" + iconURL + ">"); res.send(); }); });
终端报错信息
/Users/Desktop/code/Web Dev. Bootcamp/WeatherProject/app.js:22 const temp = weatherData.main.temp; ^ TypeError: Cannot read properties of undefined (reading 'temp') at IncomingMessage.<anonymous> (/Users/Desktop/code/Web Dev. Bootcamp/WeatherProject/app.js:22:43) at IncomingMessage.emit (node:events:513:28) at Readable.read (node:internal/streams/readable:539:10) at flow (node:internal/streams/readable:1023:34) at resume_ (node:internal/streams/readable:1004:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) Node.js v18.13.0 [nodemon] app crashed - waiting for file changes before starting...
报错指向const temp行,注释该行后会报错下一行。
解决方案
问题根源有两个:
API密钥不匹配
拼接URL时使用的apiKey值是c3fd0e578a1e8ead729deb6f25,而写死的URL里用的是c3fd0e578a1e8ead729deb6f25d(末尾多了一个d)。密钥错误会导致OpenWeatherMap API返回错误信息而非正常天气数据,此时weatherData.main为undefined,读取temp自然会触发类型错误。重复声明常量
连续两次用const声明url,这违反了JavaScript中const变量不可重复声明的规则。虽然当前代码可能因后面的声明覆盖了前面的(严格模式下会直接抛出语法错误),但这是不规范的写法,必须修正。
具体修复步骤
修正API密钥
将apiKey的值改为写死URL中的有效密钥:const apiKey = "c3fd0e578a1e8ead729deb6f25d";删除重复的
url声明
只保留拼接生成的url(这种方式更利于后续参数修改):// 仅保留这一行 const url = "https://api.openweathermap.org/data/2.5/weather?q=" + query + "&appid=" + apiKey + "&units=" + unit;添加错误处理(可选但推荐)
为了避免API返回错误时应用崩溃,可以在解析数据后先判断请求状态:response.on("data", function(data) { const weatherData = JSON.parse(data); // 检查API返回的状态码 if (weatherData.cod !== 200) { res.send("<h1>获取天气失败:" + weatherData.message + "</h1>"); return; } // 后续正常处理逻辑 const temp = weatherData.main.temp; const weatherDescription = weatherData.weather[0].description; // ... 其余代码 });
内容的提问来源于stack exchange,提问作者Eduard
相关产品推荐
相关产品推荐

