3步学会Nativefier网络拦截:从API Mock到数据篡改实战指南

3步学会Nativefier网络拦截:从API Mock到数据篡改实战指南

【免费下载链接】nativefier Make any web page a desktop application 【免费下载链接】nativefier 项目地址: https://gitcode.com/gh_mirrors/na/nativefier

你是否遇到过这些困扰?测试环境接口不稳定导致开发受阻,想修改网页数据却找不到后台配置,调试第三方API受限于请求频率?Nativefier作为一款能将任何网页转化为桌面应用的开源工具,不仅支持基础封装功能,其内置的网络请求拦截能力还能帮你轻松解决这些问题。本文将通过3个实用场景,带你掌握Nativefier的网络拦截技巧,读完你将学会:

  • 使用webRequest API拦截任意网络请求
  • 实现API响应数据的动态篡改
  • 配置请求过滤规则优化拦截效率

拦截原理与核心模块解析

Nativefier基于Electron构建,其网络拦截功能主要依赖Electron的session.webRequest模块。在app/src/helpers/windowHelpers.ts中,开发团队通过injectCSS函数展示了请求拦截的典型实现:

browserWindow.webContents.session.webRequest.onResponseStarted(
  { urls: [] }, // 空数组表示拦截所有URL
  (details: OnResponseStartedListenerDetails): void => {
    injectCSSIntoResponse(details, cssToInject).catch((err: unknown) => {
      log.error('injectCSSIntoResponse ERROR', err);
    });
  },
);

这段代码位于injectCSS函数内,原本用于在页面加载时注入自定义CSS。我们可以借鉴这种模式,将其改造为通用的请求拦截器。关键实现包含三个部分:

  1. 拦截时机选择:Electron提供了多个拦截时机,常用的有onBeforeSendHeaders(发送请求前)、onHeadersReceived(接收响应头后)和onResponseStarted(开始接收响应体时)

  2. 请求过滤规则:通过urls参数设置URL匹配模式,支持通配符如["https://api.example.com/*"]

  3. 响应处理函数:在回调函数中修改请求/响应数据,实现拦截逻辑

场景一:API Mock实现无后端开发

当后端API尚未开发完成时,我们可以使用Nativefier拦截特定请求并返回模拟数据。以下是实现步骤:

1. 创建Mock数据文件

在项目根目录创建mock-data文件夹,添加JSON格式的模拟数据文件user-profile.json

{
  "code": 200,
  "data": {
    "name": "测试用户",
    "avatar": "https://via.placeholder.com/100",
    "role": "admin"
  }
}

2. 实现请求拦截逻辑

修改app/src/helpers/windowHelpers.ts,添加请求拦截函数:

export function setupRequestMock(window: BrowserWindow) {
  const { session } = window.webContents;
  
  // 拦截用户信息API
  session.webRequest.onBeforeRequest(
    { urls: ["https://api.example.com/user/*"] },
    (details, callback) => {
      // 读取本地Mock文件
      const mockPath = path.join(__dirname, '../../mock-data/user-profile.json');
      const mockData = fs.readFileSync(mockPath, 'utf8');
      
      // 返回Mock数据
      callback({
        cancel: false,
        redirectURL: `data:application/json,${encodeURIComponent(mockData)}`
      });
    }
  );
}

3. 注册拦截函数

在窗口创建后调用拦截函数,找到createNewWindow函数(同样位于app/src/helpers/windowHelpers.ts),添加:

export function createNewWindow(
  options: WindowOptions,
  setupWindow: (options: WindowOptions, window: BrowserWindow) => void,
  url: string,
  parent?: BrowserWindow,
): BrowserWindow {
  // ... 原有代码 ...
  
  // 添加Mock拦截器
  setupRequestMock(window);
  
  window.loadURL(url).catch((err) => log.error('window.loadURL ERROR', err));
  return window;
}

这种方式适用于前后端分离项目的并行开发,通过拦截特定API请求,前端开发者可以完全独立于后端进度进行开发和测试。

场景二:响应数据实时篡改

有时我们需要临时修改API返回的数据,比如隐藏测试环境的广告内容或调整UI展示数据。以下是实现动态篡改的示例:

1. 实现响应篡改逻辑

app/src/helpers/windowHelpers.ts中添加响应处理函数:

function modifyApiResponse(details: OnResponseStartedListenerDetails) {
  // 只处理JSON响应
  const contentType = details.responseHeaders?.['content-type']?.[0];
  if (!contentType?.includes('application/json')) return;
  
  // 读取原始响应体
  const filter = { urls: [details.url] };
  session.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
    // 修改请求头,强制返回JSON格式
    details.requestHeaders['Accept'] = 'application/json';
    callback({ requestHeaders: details.requestHeaders });
  });
  
  // 替换响应数据
  session.webRequest.onResponseStarted(filter, (details) => {
    details.webContents.executeJavaScript(`
      fetch("${details.url}")
        .then(res => res.json())
        .then(data => {
          // 隐藏广告数据
          if (data.ads) data.ads = [];
          // 修改价格显示
          if (data.price) data.price = (data.price * 0.8).toFixed(2);
          // 触发自定义事件通知页面数据已更新
          window.dispatchEvent(new CustomEvent('mock-data-updated', { detail: data }));
        })
    `);
  });
}

2. 配置URL过滤规则

为避免拦截所有请求影响性能,我们可以通过URL模式精确匹配需要处理的API:

// 只拦截商品列表和详情API
const targetUrls = [
  "https://api.example.com/products/*",
  "https://api.example.com/product/detail/*"
];

session.webRequest.onResponseStarted(
  { urls: targetUrls },
  (details) => modifyApiResponse(details)
);

这种技术特别适合前端调试,无需等待后端修改接口,就能直接在客户端调整数据展示效果。

场景三:请求头与参数修改

在某些场景下,我们需要动态修改请求头或参数,比如添加认证Token、切换API版本等。以下是修改请求头的实现示例:

export function setupAuthInterceptor(window: BrowserWindow, token: string) {
  const { session } = window.webContents;
  
  session.webRequest.onBeforeSendHeaders(
    { urls: ["https://api.example.com/*"] },
    (details, callback) => {
      // 添加认证头
      details.requestHeaders['Authorization'] = `Bearer ${token}`;
      // 修改API版本
      details.requestHeaders['X-API-Version'] = 'v2';
      
      callback({ requestHeaders: details.requestHeaders });
    }
  );
}

使用时只需在创建窗口后调用:

// 在createNewWindow函数中添加
setupAuthInterceptor(window, "your-auth-token-here");

高级技巧:拦截规则优化

当拦截大量请求时,合理的过滤规则能显著提升性能。Nativefier在app/src/helpers/windowHelpers.tsinjectCSSIntoResponse函数中展示了一种高效的内容类型过滤方法:

// 拒绝列表过滤而非白名单
const nonInjectableContentTypes = [
  /application\/.*/,
  /font\/.*/,
  /image\/.*/,
];
const nonInjectableResourceTypes = ['image', 'script', 'stylesheet', 'xhr'];

if (
  (contentType && nonInjectableContentTypes.some(x => x.test(contentType))) ||
  nonInjectableResourceTypes.includes(details.resourceType)
) {
  // 跳过不需要处理的请求
  return Promise.resolve(undefined);
}

我们可以扩展这种思路,实现更精细的过滤策略:

  1. 按资源类型过滤:通过details.resourceType区分请求类型(xhr、fetch、image等)
  2. 按响应状态码过滤:只处理2xx成功响应
  3. 按内容大小过滤:跳过大型文件(如视频、压缩包)

常见问题与解决方案

1. 拦截不生效问题

如果发现拦截逻辑没有执行,可按以下步骤排查:

  • 检查URL匹配模式是否正确,注意特殊字符需要转义
  • 确认拦截时机是否合适,onBeforeSendHeaders无法获取响应数据
  • 查看控制台日志,通过app/src/helpers/loggingHelper.ts添加调试信息

2. 跨域请求处理

当拦截跨域请求时,需要注意CORS头的设置:

// 在onHeadersReceived中添加CORS头
session.webRequest.onHeadersReceived(
  { urls: ["https://api.example.com/*"] },
  (details, callback) => {
    details.responseHeaders['Access-Control-Allow-Origin'] = ['*'];
    details.responseHeaders['Access-Control-Allow-Methods'] = ['GET, POST, OPTIONS'];
    callback({ responseHeaders: details.responseHeaders });
  }
);

3. 性能优化建议

  • 避免使用空数组{ urls: [] }拦截所有请求
  • 及时移除不再需要的拦截器
  • 复杂处理逻辑使用Web Worker避免阻塞主线程

总结与扩展应用

通过本文介绍的方法,我们可以基于Nativefier实现强大的网络请求拦截功能。这些技巧不仅适用于前端开发调试,还能扩展出更多实用工具:

  • API测试工具:拦截请求并验证参数合法性
  • 前端性能分析:统计接口响应时间,识别慢请求
  • 内容过滤工具:屏蔽网页广告和追踪请求

Nativefier的网络拦截能力为桌面应用开发提供了更多可能性。你可以在src/helpers/目录下找到更多网络相关的辅助函数,结合本文介绍的方法,构建更强大的自定义拦截器。

最后提醒,网络拦截功能应仅用于开发调试和合法测试,遵守相关法律法规和网站使用条款。如果你有更复杂的拦截需求,可以参考Electron官方文档的webRequest API章节,探索更多高级用法。

【免费下载链接】nativefier Make any web page a desktop application 【免费下载链接】nativefier 项目地址: https://gitcode.com/gh_mirrors/na/nativefier

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值