You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 12:35:08