调用API获取数据时触发SyntaxError:非JSON响应问题排查
React请求OpenWeatherMap API返回HTML导致JSON解析错误
请求OpenWeatherMap API时触发以下错误:
"SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON at App.js:24:1"
手动在浏览器中访问API链接能正常获取JSON响应,但代码中发起请求时返回的是React项目的HTML页面,无法解析为JSON。
相关代码
App.js
import { useState } from "react"; import "./App.css"; import CurrentWeather from "./component/current-weather/current-weather"; import { WEATHER_API_KEY, WEATHER_API_URL } from "./component/search/api"; import Search from "./component/search/search"; function App() { const [currentWeather, setCurrentWeather] = useState(null); const [forecast, setForecast] = useState(null); const handleOnSearchChange = (searchData) => { const [lat, lon] = searchData.value.split(" "); const currentWeatherFetch = fetch( `${WEATHER_API_URL}/weather?lat=${lat}&lon=${lon}&appid=${WEATHER_API_KEY}` ); const forecastFetch = fetch( `${WEATHER_API_URL}/forecast?lat=${lat}&lon={${lon}&appid=${WEATHER_API_KEY}` ); Promise.all([currentWeatherFetch, forecastFetch]) .then(async (response) => { const weatherResponse = await response[0].json(); const forcastResponse = await response[1].json(); setCurrentWeather({ city: searchData.label, ...weatherResponse, }); setForecast({ city: searchData.label, ...forcastResponse }); }) .catch(console.log); }; console.log(currentWeather); console.log(forecast); return ( <div className="container"> <Search onSearchChange={handleOnSearchChange} /> <CurrentWeather /> </div> ); } export default App;
api.js
export const geoApiOptions = { method: "GET", headers: { "X-RapidAPI-Key": process.env.REACT_APP_GEODB_API_KEY, "X-RapidAPI-Host": "wft-geo-db.p.rapidapi.com", }, }; export const GEO_API_URL = "https://wft-geo-db.p.rapidapi.com/v1/geo"; export const WEATHER_API_URL = "api.openweathermap.org/data/2.5"; export const WEATHER_API_KEY = process.env.REACT_APP_WEATHER_API_KEY;
问题原因及修复步骤
1. API地址缺少协议前缀
WEATHER_API_URL定义时未添加https://前缀,导致fetch请求被当作相对路径发送到React开发服务器,服务器返回项目的HTML页面(而非目标API的JSON数据)。
修复api.js中的地址:
export const WEATHER_API_URL = "https://api.openweathermap.org/data/2.5";
2. forecast请求URL存在语法错误
forecastFetch的URL中,lon={${lon}}多了一个多余的左大括号,导致URL格式错误,触发无效请求。
修复App.js中的URL:
const forecastFetch = fetch( `${WEATHER_API_URL}/forecast?lat=${lat}&lon=${lon}&appid=${WEATHER_API_KEY}` );
3. 可选优化:增加响应状态检查
为避免非成功响应(如404、500)时解析JSON报错,建议在处理响应前先验证状态:
Promise.all([currentWeatherFetch, forecastFetch]) .then(async (responses) => { const [weatherRes, forecastRes] = responses; if (!weatherRes.ok) throw new Error(`天气请求失败:${weatherRes.status}`); if (!forecastRes.ok) throw new Error(`预报请求失败:${forecastRes.status}`); const weatherResponse = await weatherRes.json(); const forecastResponse = await forecastRes.json(); setCurrentWeather({ city: searchData.label, ...weatherResponse }); setForecast({ city: searchData.label, ...forecastResponse }); }) .catch(err => console.error('请求出错:', err));
内容的提问来源于stack exchange,提问作者Aadil Khatri
相关产品推荐
相关产品推荐

