通过拦截 fetch 原型方法并包装 promise,可以在请求发出前和响应返回后统一执行审计逻辑。具体做法是保存原始 window.fetch 引用,重新定义全局 fetch 函数,在调用原方法前后分别记录请求参数和响应状态,并将处理后的结果或错误透传回调用方。

如何拦截 fetch 请求以捕获请求参数
在请求发送阶段,可以通过修改 Request 对象或直接读取 init 参数来获取 URL、方法和 Headers。由于 fetch 的第二个参数是配置对象,直接访问该对象即可获取大部分信息;对于 Body 数据,若为 FormData 或 JSON,需进行序列化或遍历提取,以便在审计日志中保留具体内容。

const originalFetch = window.fetch;
window.fetch = async function(url, init = {}) {
const auditData = {
url: typeof url === 'string' ? url : url.url,
method: init.method || 'GET',
headers: init.headers,
timestamp: new Date().toISOString()
};
if (init.body) {
try {
auditData.body = JSON.parse(init.body);
} catch (e) {
auditData.body = String(init.body);
}
}
console.log('Request Audit:', auditData);
return originalFetch.apply(this, arguments);
};
如何拦截 fetch 响应以捕获返回数据
在响应返回阶段,需要解析 Response 对象的内容。由于 fetch 返回的是 Promise,我们可以在 .then() 链中处理响应。对于文本或 JSON 类型的响应,可以调用 response.text() 或 response.json() 提取内容并进行审计,但需注意多次读取 Body 会消耗流,因此必须创建克隆副本或使用中间件模式确保原响应可被后续代码正常消费。

const originalFetch = window.fetch;
window.fetch = async function(url, init = {}) {
// ... 请求审计代码 ...
const response = await originalFetch.apply(this, arguments);
const auditResponse = response.clone();
let responseData = null;
try {
const contentType = auditResponse.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
responseData = await auditResponse.json();
} else {
responseData = await auditResponse.text();
}
} catch (e) {
responseData = 'Parse Error';
}
console.log('Response Audit:', {
status: response.status,
data: responseData
});
return response;
};
如何处理并发请求导致的日志混乱问题
当多个 fetch 请求并发时,简单的 console.log 会导致输出交错难以追踪。解决方案是为每个请求生成唯一的 traceId,并将其注入到请求 Header 中,同时在响应审计时携带该 ID。这样在日志系统中可以通过 traceId 将请求与对应的响应关联起来,确保审计数据的完整性和顺序性。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











