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();
    }

相关推荐
程序员码歌18 小时前
短思考第268天,自媒体路上的4大坑点,很多人都踩过
android·前端·ai编程
黎明初时18 小时前
React基础框架搭建5-路由配置:react+router+redux+axios+Tailwind+webpack
前端·react.js·webpack
遗憾随她而去.19 小时前
前端竞态问题
前端
代码游侠19 小时前
应用——Web服务器项目代码解析
运维·服务器·开发语言·前端·笔记·html
C_心欲无痕19 小时前
网络相关 - 常用命令详解Telnet、Ping 及其他实用工具
前端·网络
JarvanMo20 小时前
没有人比我更懂Flutter第三方依赖鸿蒙化了之Sqflite
前端
子洋20 小时前
AI Agent 设计模式 - PlanAndExecute 模式
前端·人工智能·后端
web小白成长日记20 小时前
自定义 Hooks 的用法和意义详解(结合案例)
前端·css·面试·职场和发展·前端框架
小鸡脚来咯20 小时前
前端传输的数据格式的选择
java·开发语言·前端·后端