在 Electron 应用中,你完全掌控应用内发生的所有网络通信。session 的 webRequest 系列 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.handle 或 protocol.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等回调必须同步返回结果),避免在其中做耗时的计算或网络请求。如需异步处理,务必在新的会话中启用webRequest的asyncBlocking模式(Electron 在较新版本中已支持部分异步 API)。 - filter 精确匹配:不要无差别拦截所有 URL,始终用
urls数组限制范围,减少无关请求的处理开销。 - 多个拦截器顺序:如果多个地方注册了
onBeforeRequest,它们会按照注册顺序依次调用。如果需要更复杂的控制,可以自己维护一个中间件数组。 - 调试工具:
session.defaultSession.webRequest的回调可以通过 Chrome DevTools 的 Network 面板观察结果,结合console.log快速定位被修改的请求。
通过 session 网络请求代理,你的 Electron 应用拥有了一种“全知全能”的网络控制能力。它是实现高级功能(如本地缓存、统一认证、请求审计)的底层基础,也是让桌面应用真正具备“原生级”网络掌控感的关键技术。掌握好这些 API,你可以把前端网页本该依赖服务器做的事情,直接在客户端完成,大幅提升应用的灵活性和用户体验。