Electron使用protocol.handle拦截HTTP请求时如何获取Payload?
解决Electron protocol.handle拦截HTTP请求时无法获取请求体的问题
你的问题出在对protocol.handle传入的Request对象的使用方式上,以下是修复方案:
关键问题点
- 无需
await req:req本身就是标准的Request实例,不需要额外await - 要区分请求方法:GET、HEAD这类方法没有请求体,直接调用
json()会报错 - 处理请求体时建议加异常捕获:避免请求体格式不符合JSON导致程序崩溃
修复后的代码
app.whenReady() .then(() => { createWindow(); // Add API protocol.handle('http', async (req) => { const { host, pathname } = new URL(req.url); if (pathname.substring(0, 5) === '/api/') { console.log(`Api request intercepted ${host} + ${pathname}`); // 仅处理带请求体的方法 let requestBody = null; if (['POST', 'PUT', 'PATCH'].includes(req.method)) { try { requestBody = await req.json(); console.log('请求体:', requestBody); } catch (err) { console.error('解析请求体失败:', err); // 若JSON解析失败,可尝试获取文本格式 requestBody = await req.text(); console.log('文本格式请求体:', requestBody); } } return new Response(JSON.stringify({ code: 200, data: 'success' }), { headers: { 'Content-Type': 'application/json' } }); } // 转发其他请求 return net.fetch(req.url, { method: req.method, headers: req.headers, body: req.body, bypassCustomProtocolHandlers: true, }); }); app.on('activate', () => { if (mainWindow === null) createWindow(); }); }) .catch(console.log);
补充说明
Request对象的body是一个可读流,只能被读取一次,所以如果你在拦截逻辑中已经读取了请求体(比如调用了json()或text()),那么转发请求时就不能再用req.body了,需要重新构建body内容- 如果你需要支持多种请求体格式(比如form-data、x-www-form-urlencoded),可以根据
Content-Type请求头来选择对应的解析方式,比如用req.formData()处理表单数据
内容的提问来源于stack exchange,提问作者Lau
相关产品推荐
相关产品推荐

