Chrome插件开发如何监听接口请求

2,641 阅读2分钟

背景

最近公司开新坑,许多接口只有Swagger文档,前端自测的时候需要mock,在网上找了一圈,没找到基于swagger应用场景的mock工具,于是自己动手撸了一个谷歌插件SwaggerMockGenerator,原理也比较简单,就是劫持接口请求,然后根据swagger文档生成数据,并改写接口返回的数据,但就是这么一个劫持接口的方法,我在网上找了一圈,愣是没找到比较好的解决方法,其中大部分写的都是使用chrome提供的background方法,在后台挂载一个监听接口的进程,但由于MV3中background的生命周期不能在后台常驻了,而是插件加载完成后会自动进入休眠状态,只有手动触发才会唤醒,实现起来比较麻烦,所以我想了一个比较简单但是又比较“脏”的方法,接下来是实现方法。

监听接口请求

原理

已知Content Script和原始页面共享DOM,但是不共享JS,所以可以使用Content Script给页面注入一段脚本,利用第三方库ajax-hooks来劫持并篡改接口返回的数据。

实现

使用ajax-hooks监听接口

// inject.ts
import { proxy } from "ajax-hook";

proxy({
  //请求发起前进入
  onRequest: (config, handler) => {
    handler.next(config);
  },
  //请求发生错误时进入,比如超时;注意,不包括http状态码错误,如404仍然会认为请求成功
  onError: (err, handler) => {
    handler.next(err);
  },
  //请求成功后进入
  onResponse: (res, handler) => {
    const { url, method } = res?.config || {};
    try {
      // 假设后端有个获取用户信息的接口/accounts/profile
      if(url.includes("/accounts/profile" && method.toUpperCase() === "GET")){
        // 设置接口状态为200,这样就算后端服务挂了,接口依然可以返回数据
        res.status = 200;
        // 改变接口的数据
        res.response = {
          code: 200,
          data: {
            accountId: "777",
            name: "张三",
            gender: "男",
            like: "唱、跳、rap",
          },
          message: "success",
        };
      }
    } finally {
      handler.next(response);
    }
  },
});

注入inject.ts脚本

// content-script.ts

const script = document.createElement("script");
script.setAttribute("src", chrome.runtime.getURL("你的inject脚本目录/xxx.js"));
document.head.appendChild(script);

修改Manifest配置

// manifest.json
{
  ...
  content_scripts: [
    {
      matches: ["http://*/*", "https://*/*", "<all_urls>"],
      js: ["你的content脚本目录/xxx.js"],
    },
  ],
  ...
}

详细的代码可以查看SwaggerMockGenerator

结语

虽然给页面注入脚本的方法不太好,但胜在简单、容易实现,我也尝试使用chrome.webRequest实现过,但是很不稳定,有些接口老是监听不到,所以就分享了这个方法,如果有其他方法,欢迎在评论区里推荐👏🏻。

相关文档