Vue项目fetch调用指定API时出现Promise未捕获json读取报错
问题现象
- Vue生产环境项目中,相同
fetch写法调用其他接口全部运行正常,仅调用目标产品接口时抛出Promise错误 - 错误信息:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'json') - 原问题代码:
import { ref } from "vue"; export default { async setup() { const prompProducts = ref(null); const bc_prompProducts = await fetch( "https://booking.hemantbhutanrealestate.com/api/v1/get_frontend_products" ); prompProducts.value = await bc_prompProducts.json(); return { prompProducts, }; }, };
根因分析
报错直接触发原因是await fetch(...)的返回值为undefined,后续对undefined调用.json()方法触发类型错误。结合「同逻辑其他接口正常、仅单接口触发、仅生产环境出现」的特征,问题来源可以锁定为两类:
- 请求被客户端规则拦截
生产环境用户侧安装的广告拦截插件(AdBlock、uBlock Origin等)、浏览器内置隐私保护规则、企业网络网关拦截规则,命中了该接口的特征:接口路径带products关键词、域名属于房产交易类,被规则判定为广告/推广内容直接拦截,部分拦截逻辑不会抛出标准请求错误,直接导致fetch返回undefined。 - 代码无异常兜底逻辑
现有代码没有任何异常捕获、返回值合法性校验逻辑:只要fetch请求因为任意原因没有返回标准Response对象(CORS配置偶发失效、网关超时返回空、CDN回源失败、插件拦截),就会直接触发报错,且未被捕获的Promise错误会直接中断当前组件的渲染流程。
修复方案
第一步:补全代码容错逻辑,先阻断报错影响线上页面
给请求加全链路异常捕获和返回值校验,异常场景返回兜底默认值,避免页面白屏,修改后代码如下:
import { ref } from "vue"; export default { async setup() { const prompProducts = ref([]); try { const bc_prompProducts = await fetch( "https://booking.hemantbhutanrealestate.com/api/v1/get_frontend_products" ); // 校验返回值为合法Response对象且HTTP状态正常 if (bc_prompProducts?.ok) { prompProducts.value = await bc_prompProducts.json(); } else { // 异常场景打日志,方便排查 console.error("产品接口请求异常,状态码:", bc_prompProducts?.status); } } catch (err) { // 捕获网络错误、跨域错误、插件拦截等所有请求阶段异常 console.error("产品接口请求失败:", err); } return { prompProducts, }; }, };
第二步:解决接口被拦截的根因
- 先做本地验证:打开浏览器无痕模式(默认禁用所有第三方插件)访问生产页面,如果接口请求正常、无报错,即可确认是拦截插件/规则导致的问题
- 调整接口路径命名,避开拦截规则关键词:将路径中的
get_frontend_products修改为无广告指向性的业务命名,比如get_property_list - 配置同域名反向代理:将该接口代理到当前站点域名下,避免直接跨域调用第三方域名,可同时解决跨域偶发问题、大幅降低被拦截概率
- 增加1-2次自动重试逻辑:首次请求失败时自动重试,覆盖偶发网络波动、临时拦截的场景
内容的提问来源于stack exchange,提问作者Ujwal Pradhan
相关产品推荐
相关产品推荐

