
本文详解因自定义 window.fetch 拦截器未正确调用原生 fetch 并遗漏 return 语句,导致 response.json() 报错 “cannot read properties of undefined” 的根本原因与完整修复方案。
本文详解因自定义 window.fetch 拦截器未正确调用原生 fetch 并遗漏 return 语句,导致 response.json() 报错 “cannot read properties of undefined” 的根本原因与完整修复方案。
在使用 fetch 进行表单提交或 API 调用时,若通过重写 window.fetch 实现请求拦截(如日志记录、鉴权注入等),极易因语法与逻辑疏漏引发运行时错误。你遇到的 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'json'),本质并非 JSON 解析问题,而是 .then() 链中接收到的 response 为 undefined —— 根源在于自定义 fetch 函数既未调用原生 fetch,也未显式返回响应对象。
? 错误代码解析
原始代码存在两个关键缺陷:
-
未调用原生 fetch:
const response = await(resource, config); // ❌ 错误!这是逗号表达式,等价于 await config
此处 await(resource, config) 并非函数调用,而是 JavaScript 逗号操作符:它先计算 resource,再计算并返回 config,最终 await config 尝试等待一个配置对象(非 Promise),导致逻辑崩溃且 response 值异常。
缺少 return 语句:
异步箭头函数若无显式 return,默认返回 undefined。因此拦截后的 fetch() 调用实际返回 Promise,后续 .then(response => response.json()) 中的 response 即为 undefined,自然无法调用 .json() 方法。
✅ 正确实现方式
需同时满足两个条件:调用原始 fetch + 返回其 Promise 结果。修复后代码如下:
<script>
// 保存原生 fetch
const { fetch: originalFetch } = window;
// 安全覆盖 window.fetch
window.fetch = async (...args) => {
const [resource, config] = args;
console.log("? Intercepted request to:", resource);
console.log("⚙️ Config:", config);
try {
// ✅ 正确调用原生 fetch,并 await 其返回的 Response 对象
const response = await originalFetch(resource, config);
console.log("✅ Got response:", response.status, response.statusText);
// ✅ 必须返回 response,确保链式调用可继续
return response;
} catch (error) {
console.error("❌ Fetch failed:", error);
throw error; // 保持错误透传,避免静默失败
}
};
// 使用示例:POST 请求并解析 JSON 响应
fetch("/form-1.html", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Alice", email: "alice@example.com" })
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json(); // ✅ 此时 response 已是有效 Response 实例
})
.then(json => console.log("? Parsed JSON:", json))
.catch(err => console.error("? Handling error:", err));
</script>
⚠️ 注意事项与最佳实践
-
永远 return 原生 fetch 的结果:拦截器的核心是“增强而非替换”,返回值必须与原生 fetch 一致(即 Promise
)。 - 勿滥用 npm install json:浏览器原生 Response.json() 是内置方法,无需额外安装任何包;该命令仅适用于 Node.js 环境下的 JSON 处理库,与前端 fetch 无关。
- 添加错误处理:使用 try/catch 捕获网络异常或 CORS 错误,避免拦截器自身引发未捕获拒绝(unhandled rejection)。
- 谨慎修改全局行为:生产环境建议使用更可控的封装(如自定义 apiClient 工具函数),而非直接覆盖 window.fetch,以防第三方库兼容性问题。
- 验证响应状态:.json() 前建议检查 response.ok 或 response.status,防止对非 2xx 响应强行解析(如服务端返回 HTML 错误页)。
遵循以上修正,即可彻底解决 response.json() is not a function 类型错误,让 fetch 拦截器稳定、可靠地服务于表单提交与 API 交互场景。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











