人人都会AI编程

13.4 请求拦截与修改:session 网络请求代理

更新时间:2026-07-11

在 Electron 应用中,你完全掌控应用内发生的所有网络通信。sessionwebRequest 系列 API 提供了与 Chrome 扩展中的 chrome.webRequest 几乎一致的接口,允许你在请求的各个生命周期阶段插入自定义逻辑——修改请求头、重定向请求、拦截响应、篡改返回数据,甚至完全阻止一些请求发出。

这项能力在以下真实场景中尤其有用:

  • 统一注入认证信息:为所有 API 请求自动附加 Token,免去在每个 fetch 调用里手动加头。
  • 离线化与缓存:拦截特定静态资源请求,改为从本地文件系统读取,实现速度极快、无需网络的启动。
  • 广告过滤与隐私保护:阻止应用内的请求打到遥测、广告或跟踪域名,减少带宽浪费并提升性能。
  • 自定义协议:将 https://myapp.local/ 这类自定义域名的请求映射到本地文件或内存数据,便于多窗口或沙盒环境下的资源加载。

13.4.1 拦截请求并修改请求头

最常见的需求:在每一个发出的请求上附加认证头,而不希望在前端代码里到处写 Authorization。使用 session.defaultSession.webRequest.onBeforeSendHeaders 可以轻松实现。

// main.js 或独立的网络模块
const { session } = require('electron')

// 使用默认 session(无分区)
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
  details.requestHeaders['Authorization'] = 'Bearer my-token-123'
  callback({ requestHeaders: details.requestHeaders })
})

上述代码会在每个发出的 HTTP 请求上加上 Authorization 头,包括你的页面请求、 fetch 调用、<img> 加载等。如果你只想针对特定域名生效,可以在回调里加上过滤条件:

session.defaultSession.webRequest.onBeforeSendHeaders(
  { urls: ['https://api.your-domain.com/*'] },
  (details, callback) => {
    details.requestHeaders['X-Custom-Header'] = 'AppGenerated'
    callback({ requestHeaders: details.requestHeaders })
  }
)

urls 过滤器支持标准的 匹配模式,可以是 ['://.example.com/*'] 这样的通配符。

13.4.2 拦截并修改响应

有时候你需要对返回的数据做实时加工,比如统一处理错误码、注入脚本,或在开发阶段修改 API 返回结果以便调试。

onHeadersReceived 可以修改响应头,但无法直接改动响应体;要修改响应体,需要使用 onBeforeRequest 配合 callback({ redirectURL }) 将请求重定向到本地服务器,或者结合 protocol 模块实现完全的响应接管。不过,更简单的“响应体加工”通常用 webRequest.onCompleted 配合作弊手段较难,社区常用方案是将请求托管给 protocol.interceptStreamProtocol(见 13.4.4)。

一个实用的响应头修改例子:移除某些敏感响应头,像 x-powered-by,或强制要求所有响应都带上 Content-Security-Policy

session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
  const responseHeaders = details.responseHeaders
  // 移除敏感头
  delete responseHeaders['x-powered-by']
  // 跨域兼容
  responseHeaders['Access-Control-Allow-Origin'] = ['*']
  callback({ responseHeaders })
})

13.4.3 请求重定向与阻止

onBeforeRequest 是最强大的拦截点。你可以在此阶段:

  • 重定向:将某个远程资源请求完全转向另一个地址,这在切换 API 环境或加载本地资源时非常方便。
  • 直接阻止:返回 cancel 即可中止请求,节省流量并防止隐私泄露。
session.defaultSession.webRequest.onBeforeRequest(
  { urls: ['*://*.doubleclick.net/*'] },
  (details, callback) => {
    // 直接拦截广告/跟踪请求
    callback({ cancel: true })
  }
)

session.defaultSession.webRequest.onBeforeRequest(
  { urls: ['https://unpkg.com/*'] },
  (details, callback) => {
    // 重定向到本地替代
    const localUrl = `file://${__dirname}/local-assets/${details.url.split('/').pop()}`
    callback({ redirectURL: localUrl })
  }
)

注意,重定向到的 URL 协议必须清晰,Electron 的 webRequest 支持 file://、自定义协议等。

13.4.4 使用自定义协议实现响应内容篡改

真正的“响应内容修改”(如在特定 JSON 响应里添加字段)需要接管整个资源加载过程。protocol.handleprotocol.interceptStreamProtocol 允许你注册一个自定义的协议或拦截一个已有的协议(比如 https),然后由你的代码决定返回什么数据。

这类操作能实现:将 https://myapp.local/ 请求转换为从磁盘读取的本地文件,或返回由 JavaScript 动态生成的 HTML 字符串。

const { protocol } = require('electron')

protocol.handle('myapp', (request) => {
  // request.url 类似 myapp://domain/path?query
  const path = new URL(request.url).pathname

  if (path === '/') {
    return new Response('<h1>Hello from custom protocol!</h1>', {
      headers: { 'content-type': 'text/html' }
    })
  }

  // 也可以从本地文件读取
  return net.fetch('file://' + __dirname + path)
})

对于修改现有 https 响应,可以用 interceptStreamProtocol 实现一个中间人:

protocol.interceptStreamProtocol('https', (request, callback) => {
  // 仅对特定域名生效
  if (!request.url.startsWith('https://api.example.com')) {
    // 若不处理,释放逻辑让 Chromium 正常加载
    callback({}) 
    return
  }

  // 通过 Node.js 获取原始响应
  const https = require('https')
  https.get(request.url, { headers: request.headers }, (res) => {
    let data = ''
    res.on('data', chunk => data += chunk)
    res.on('end', () => {
      // 修改响应内容
      const modified = JSON.parse(data)
      modified._injected = true
      callback({
        statusCode: 200,
        headers: { 'content-type': 'application/json' },
        data: Buffer.from(JSON.stringify(modified))
      })
    })
  }).on('error', (err) => {
    callback({ error: -2 }) // 失败返回错误码
  })
})

⚠️ 注意:拦截 https 协议有安全风险,需要对证书进行信任处理,否则会导致 SSL 错误。建议在确定可信的环境下使用,并且尽量用自定义协议代替直接拦截 https

13.4.5 实战技巧与注意事项

  • 性能影响webRequest 的拦截函数是同步阻塞的(onBeforeRequest 等回调必须同步返回结果),避免在其中做耗时的计算或网络请求。如需异步处理,务必在新的会话中启用 webRequestasyncBlocking 模式(Electron 在较新版本中已支持部分异步 API)。
  • filter 精确匹配:不要无差别拦截所有 URL,始终用 urls 数组限制范围,减少无关请求的处理开销。
  • 多个拦截器顺序:如果多个地方注册了 onBeforeRequest,它们会按照注册顺序依次调用。如果需要更复杂的控制,可以自己维护一个中间件数组。
  • 调试工具session.defaultSession.webRequest 的回调可以通过 Chrome DevTools 的 Network 面板观察结果,结合 console.log 快速定位被修改的请求。

通过 session 网络请求代理,你的 Electron 应用拥有了一种“全知全能”的网络控制能力。它是实现高级功能(如本地缓存、统一认证、请求审计)的底层基础,也是让桌面应用真正具备“原生级”网络掌控感的关键技术。掌握好这些 API,你可以把前端网页本该依赖服务器做的事情,直接在客户端完成,大幅提升应用的灵活性和用户体验。