Fetch请求返回HTML而非JSON,调用res.json()出现Promise被拒绝如何解决?
问题根因判定
该异常不是环境变量配置错误导致,核心是异步时序问题与React开发服务器 fallback 规则共同作用的结果:
navigator.geolocation.getCurrentPosition是异步回调接口,调用后未等待回调执行就直接发起fetch请求,此时lat、long仍为初始空值/默认值,拼接出的请求URL参数异常- React开发服务器默认开启SPA路由 fallback 规则:所有未匹配到静态资源/接口的请求,都会返回public目录下的index.html,异常URL刚好命中该规则,因此拿到HTML内容而非JSON
- 直接在控制台执行fetch返回pending是正常现象,fetch本身返回Promise对象,需要通过await或
.then()才能获取最终响应结果,直接打印只会显示pending状态
修复方案
1. 修正异步请求时序
将fetch请求移动到坐标获取的回调中,确保请求发起时已经拿到正确的经纬度参数,参考代码:
const fetchData = async () => { navigator.geolocation.getCurrentPosition(async function(position) { const lat = position.coords.latitude; const long = position.coords.longitude; const res = await fetch(`${process.env.REACT_APP_API_URL}/weather?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`) if (!res.ok) { throw new Error(`请求异常,状态码:${res.status}`) } const data = await res.json() // 后续业务逻辑处理 }); } fetchData();
2. 环境变量校验(可选,用于确认配置正确性)
发起请求前打印完整拼接的URL,确认环境变量加载正常:
const fullReqUrl = `${process.env.REACT_APP_API_URL}/weather?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}` console.log('完整请求地址:', fullReqUrl) // 正常情况REACT_APP_API_URL的值应为 https://api.openweathermap.org/data/2.5
3. 增加异常兼容逻辑
调用res.json()前先校验响应格式,避免解析失败抛出未捕获异常:
fetch(/* 请求URL */) .then(async res => { const contentType = res.headers.get('content-type') if (contentType?.includes('application/json')) { return res.json() } const errContent = await res.text() throw new Error(`响应格式错误,预期JSON,实际返回前200字符:${errContent.slice(0, 200)}`) }) .catch(err => console.error('请求失败:', err))
内容的提问来源于stack exchange,提问作者Jelena Feliciano
相关产品推荐
相关产品推荐

