调用weatherapi.com API解析JSON时遇unexpected end of JSON input错误
解决JSON解析“unexpected end of JSON input”错误
问题原因
Node.js 的 https.get 返回的响应是流对象,data 事件会多次触发,每次仅返回部分数据(分块传输)。直接在 data 事件里解析 JSON,拿到的是不完整的数据片段,必然会触发“JSON输入意外结束”的错误。setTimeout 无法解决这个问题,因为核心矛盾是数据接收方式错误,而非异步延迟。
修复后的代码
const express = require('express'); const https = require('https'); const bodyParser = require('body-parser'); const app = express(); app.use(express.static("public")); app.use(bodyParser.urlencoded({extended:true})); app.post("/weather-data",function(req, res){ var city_name = req.body.city_name; city_name = city_name.toUpperCase(); const key = "4b6f380fa80745beb2c174529222912"; const days = 1; const url = "https://api.weatherapi.com/v1/forecast.json?key="+key+"&q="+city_name; https.get(url,(response)=>{ console.log(response.statusCode); const status = response.statusCode; if(status == 200){ // 存储完整响应数据 let rawData = ''; // 拼接分块数据 response.on("data",function(chunk){ rawData += chunk; }); // 所有数据接收完成后再解析JSON response.on("end",function(){ try { const WeatherData = JSON.parse(rawData); const region = WeatherData.location.region; const country = WeatherData.location.country; console.log("region is "+region+" and country is "+country); // 给客户端返回响应,避免请求挂起 res.send(`地区:${region},国家:${country}`); } catch (err) { console.error('JSON解析失败:', err); res.status(500).send('数据解析错误'); } }); } else { res.status(status).send('请求失败,状态码:' + status); } }).on('error', (err) => { console.error('请求出错:', err); res.status(500).send('请求出错'); }); });
额外注意事项
- 必须监听
end事件,在该事件中处理完整的响应数据,而非data事件。 - 添加
try/catch捕获 JSON 解析异常,防止程序崩溃。 - 务必给客户端返回响应(如
res.send),否则客户端请求会一直处于挂起状态。 - 建议用
const声明url,避免隐式全局变量风险。
内容的提问来源于stack exchange,提问作者Rameez Ali
相关产品推荐
相关产品推荐

