Express天气API接口部分返回313无效状态码错误求助
Express调用WeatherAPI接口报错问题排查
问题描述
开发天气应用时,使用Express框架调用weatherapi.com的API,其中/weather和/location接口可正常返回JSON数据,但/humidity、/temprature、/wind接口持续返回313(Invalid Store)错误,报错信息为RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 30,核对JSON路径无误后问题仍未解决。
初始化代码
const express = require('express'); const cors = require('cors') const request = require('request'); const PORT = 3060; const app = express() app.use(cors()); app.use(express.json());
正常工作的接口
app.get('/weather',(req,res) => { let city = req.query.city; const request = require('request'); request(`http://api.weatherapi.com/v1/current.json?key={myKEy}&q=${city}&aqi=no`, function (error, response, body) { console.log(body) let data = JSON.parse(body); if(response.statusCode === 200){ res.send(data.current.condition.text) } }); }) app.get('/location',(req,res) => { let city = req.query.city; const request = require('request'); request(`http://api.weatherapi.com/v1/current.json?key={myKEy}&q=${city}&aqi=no`, function (error, response, body) { console.log(body) let data = JSON.parse(body); if(response.statusCode === 200){ res.send(data.location.name) } }); })
报错信息
{"location":{"name":"Nanital","region":"Uttarakhand","country":"India","lat":29.38,"lon":79.45,"tz_id":"Asia/Kolkata","localtime_epoch":1670136364,"localtime":"2022-12-04 12:16"},"current":{"last_updated_epoch":1670136300,"last_updated":"2022-12-04 12:15","temp_c":25.2,"temp_f":77.4,"is_day":1,"condition":{"text":"Sunny","icon":"//cdn.weatherapi.com/weather/64x64/day/113.png","code":1000},"wind_mph":2.2,"wind_kph":3.6,"wind_degree":229,"wind_dir":"SW","pressure_mb":1014.0,"pressure_in":29.95,"precip_mm":0.0,"precip_in":0.0,"humidity":30,"cloud":0,"feelslike_c":24.8,"feelslike_f":76.6,"vis_km":10.0,"vis_miles":6.0,"uv":7.0,"gust_mph":1.3,"gust_kph":2.2}} express deprecated res.send(status): Use res.sendStatus(status) instead Server.js:61:21 node:_http_server:313 throw new ERR_HTTP_INVALID_STATUS_CODE(originalStatusCode); ^ RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 30 at new NodeError (node:internal/errors:393:5) at ServerResponse.writeHead (node:_http_server:313:11) at ServerResponse._implicitHeader (node:_http_server:304:8) at ServerResponse.end (node:_http_outgoing:993:10) at ServerResponse.send (E:\weatherapp\node_modules\express\lib\response.js:232:10) at Request._callback (E:\weatherapp\Server.js:61:21) at self.callback (E:\weatherapp\node_modules\request\request.js:185:22) at Request.emit (node:events:513:28) at Request.<anonymous> (E:\weatherapp\node_modules\request\request.js:1154:10) at Request.emit (node:events:513:28) { code: 'ERR_HTTP_INVALID_STATUS_CODE' } Node.js v18.10.0 [nodemon] app crashed - waiting for file changes before starting...
出现问题的接口代码
app.get('/humidity',(req,res) => { let city = req.query.city; const request = require('request'); request(`http://api.weatherapi.com/v1/current.json?key={myKEy}&q=${city}&aqi=no`, function (error, response, body) { console.log(body) let data = JSON.parse(body); if(response.statusCode === 200){ res.send(data.current.humidity) } }); }) app.get('/temprature',(req,res) => { let city = req.query.city; const request = require('request'); request(`http://api.weatherapi.com/v1/current.json?key={myKEy}&q=${city}&aqi=no`, function (error, response, body) { console.log(body) let data = JSON.parse(body); if(response.statusCode === 200){ res.send(data.current.temp_c) } }); }) app.get('/wind',(req,res) => { let city = req.query.city; const request = require('request'); request(`http://api.weatherapi.com/v1/current.json?key={myKEy}=${city}&aqi=no`, function (error, response, body) { console.log(body) let data = JSON.parse(body); if(response.statusCode === 200){ res.send(data.current.wind_kph) } }); }) app.listen( PORT , () => console.log(`This is Listing to port ${PORT}`) )
问题原因及解决方案
核心原因
Express的res.send()方法有特性:如果传入参数是数字类型,会被自动识别为HTTP状态码。而有效HTTP状态码范围是100-599,data.current.humidity返回的30、temp_c返回的25.2都不在该范围内,因此触发Invalid status code错误。
/weather和/location接口返回的是字符串(data.current.condition.text、data.location.name),res.send()会将其作为响应体返回,所以无问题。
解决方法
有两种修复方式:
- 将数字转换为字符串:调用
res.send()时把数字转成字符串,避免被识别为状态码// 以humidity接口为例 res.send(String(data.current.humidity)) - 使用
res.json()替代res.send():res.json()会将任何类型数据(包括数字)序列化为JSON响应体,不会误判为状态码// 以humidity接口为例 res.json(data.current.humidity)
额外修复:/wind接口URL错误
/wind接口请求URL存在拼写错误:key={myKEy}=${city}应改为key={myKEy}&q=${city},原代码把&q写成了=,会导致API请求参数错误,需修正。
内容的提问来源于stack exchange,提问作者newtocodeing
相关产品推荐
相关产品推荐

