electron中拦截请求

仅个人学习记录

缺陷:无法获取到请求头

请求头可以查看onHeadersReceived

  • electron主进程

    // 插入拦截函数
    function interceptAllRequests() {
    const { session, dialog } = require('electron'); // 补充引入拦截需要的模块

    复制代码
    // 1. 拦截普通窗口所有请求(保留软件A原有功能)
    // const defaultSession = session.defaultSession;
    
    // 2. 拦截webview所有请求(不破坏原有webview功能)
    const webviewSessions = [
      // session.defaultSession,
      // session.fromPartition('persist:app-webview'),
      // session.fromPartition('app-webview'),
      session.fromPartition('')
    ];
    webviewSessions.forEach(webSession => {
      webSession.webRequest.onBeforeRequest({
        urls: ['<all_urls>']
      },async (details, callback) => { // 改为async函数支持异步校验
        if(details.resourceType !== 'xhr'){
          // 拦截请求:true=拦截,false=放行,可自由切换
          callback({ cancel: false }); // 如需放行,改成 false 即可
          return
        }
    
        if(!details.url.endsWith('/worklist/getUserWorkListInPortal')){
          // 拦截请求:true=拦截,false=放行,可自由切换
          callback({ cancel: false }); // 如需放行,改成 false 即可
          return
        }
    
        // 2. 先处理所有业务逻辑(提取请求体 + 打印日志),再调用 callback
        let requestBody = null;
        // 提取请求体(仅 POST/PUT 等有上传数据的请求才有 uploadData)
        if (details.uploadData && details.uploadData.length > 0) {
          try {
            requestBody = details.uploadData.map(item => {
              if (item.bytes) {
                // 转为 UTF-8 字符串,兼容 JSON/表单等格式
                return Buffer.from(item.bytes).toString('utf8');
              }
              return '';
            }).join('');
            console.log(`【Webview窗口】拦截到XHR请求体:${requestBody}`);
          } catch (e) {
            requestBody = `【请求体解析失败】:${e.message}`;
            console.error(requestBody);
          }
        }
    
        // 提取WebView请求关键信息(含请求体,传给三方接口)
        const requestInfo = {
          url: details.url,
          method: details.method || 'GET',
          resourceType: details.resourceType,
          body: requestBody // 传递请求体给三方接口
        };
    
        // 【核心】调用三方接口校验
        const isValid = true //await checkApi(requestInfo);
    
        if (!isValid) {
          // 校验失败:拦截请求 + 弹出弹窗提示
          dialog.showMessageBox({
            type: 'error',
            title: 'WebView请求拦截',
            message: '请求未通过三方校验',
            detail: `被拦截的请求:${details.url}`,
            buttons: ['确定']
          });
          callback({ cancel: true }); // 拦截请求
          return;
        }
    
        const keys = Object.keys(details);
        keys.forEach(key=>{
          let value = details[key];
          try {
            if (typeof value === 'object' && value !== null) {// 处理对象类型,安全序列化
              value = JSON.stringify(value, null, 2);
            }
          } catch (e) {
            value = `【序列化失败】:${e.message}`;
          }
          if(!['uploadData', 'frame', 'webContents'].includes(key)){
            console.log(`【Webview窗口】拦截到webview请求key:${key},value:${value}`);
          }
        })
    
        console.log(`====================================================`);
    
        callback({ cancel: false }); // webview请求拦截,放行改false
      });
    });
    
    console.log('拦截器已启动,不影响软件原有功能!');

    }

    // 【核心】封装三方接口校验函数(异步)
    async function checkApi(requestInfo) {
    const axios = require('axios'); // 引入axios用于调用三方校验接口
    try {
    // 替换为你的实际三方校验接口地址
    const thirdPartyUrl = 'http://localhost:3259/api/request-handle';
    // 向三方接口传递请求关键信息(可按需增减字段)
    const response = await axios.post(thirdPartyUrl, requestInfo, {
    timeout: 5000, // 5秒超时保护
    headers: {
    'Content-Type': 'application/json' // 按三方接口要求设置请求头
    }
    });

    复制代码
      console.log('data',response.data);
    
      // 假设三方接口返回 { "valid": true/false },可根据实际返回格式调整
      return response.data.data.valid;
    } catch (err) {
      console.error('三方校验接口调用失败:', err.message);
      // 接口异常时,默认拦截(可改为 return false 拦截 / return true 放行)
      return false;
    }

    }

    app.whenReady().then(()=>{
    interceptAllRequests(); // 新增:先启动拦截(这一行是关键)
    createWindow();
    }

相关推荐
风止何安啊8 分钟前
🚦 前端并发请求 “交通管制”:别让你的接口堵成早高峰
前端·javascript·面试
J船长12 分钟前
扫盲烂笔头:A 记录、CNAME 的作用, Nginx的用途,为啥叫反向代理
前端
妙码生花18 分钟前
从 PHP 到 AI + Golang,程序员自救转型手记(二十六):icon 组件封装
前端·vue.js·typescript
李明卫杭州19 分钟前
Vue2 & Vue3 中 Router `props` 配置详解:彻底摆脱 `$route` 依赖
前端·vue.js·前端框架
掘金一周19 分钟前
裁员了,公司很爽快,赔偿一分没少 | 沸点周刊 7.8
前端·人工智能·后端
熊猫钓鱼>_>23 分钟前
2026 前端的三场底层革命:当 Vue、React Native 和 Three.js 同时去掉中间层
前端·javascript·vue.js·react native·架构·webgl·three.js
名字还没想好☜33 分钟前
React useEffect 依赖数组踩坑:闭包陷阱与清理函数
前端·javascript·react.js·react·useeffect
宸翰1 小时前
uni-app 设置 Android 底部虚拟导航栏背景色
android·前端·uni-app
柒和远方2 小时前
LeetCode 4. 寻找两个正序数组的中位数 —— 二分划分的艺术
javascript·python·算法
金色的暴发户2 小时前
一劳永逸解决Codex手机验证
前端·人工智能·开源