在一个后台页面里,把请求头改成测试环境的标记,看起来只需要两个输入框:名称和值。
真正麻烦的是后面的问题。这个配置影响当前标签页,还是同一个域名的所有请求?切到另一个站点还生效吗?关掉一组配置再打开,原来禁用的某一条规则会不会被误开?
我做 RequestKit 时,最在意的就是这些边界。一个开发工具可以功能少,但用户应该能预判它下一步会做什么。
当前页面和请求目标,是两件事
假设地址栏里是一个管理后台:
text当前页面 https://admin.example.com 页面发出的请求 https://api.example.com/orders
如果给 admin.example.com 建了一组规则,它是否应该影响发往 api.example.com 的请求?两种答案都能做成产品,关键是选定一种,并让界面和实际执行一致。
RequestKit 的 Per site 模式按请求目标的精确 hostname 匹配。上面的 API 请求需要 api.example.com 自己的配置。当前标签页只是帮助弹窗找到正在编辑的站点,不会把这个页面发出的所有第三方请求都纳入同一组规则。匹配实现
以 api.example.com 为例:
| 请求地址 | 是否属于这组配置 |
|---|---|
| https://api.example.com/orders | 是 |
| https://api.example.com:8443/orders | 是,端口不改变 hostname |
| https://v2.api.example.com/orders | 否,子域名单独配置 |
| https://example.com/?next=api.example.com | 否,查询参数里的文字不是请求主机 |
所以“只对这个站点生效”还不够准确。真正需要表达的是“发往这个确切主机的请求”。一个词说得含糊,调试时就可能多绕一圈。
开关应该暂停配置,而不是重写配置
RequestKit 有 Per site 和 All sites 两种互斥模式,后者面向所有 HTTP/HTTPS 站点。两种模式各自保存配置,切换模式只改变当前采用哪一套规则。
在一套配置内部,还要区分整组开关与单条开关。假设 A、B 两条规则开启,C 关闭;把整组暂停后再启用,合理的结果仍然是 A、B 开启,C 关闭。
如果总开关直接把每条规则的 enabled 都改成 false,用户原来的选择就消失了。更稳妥的模型是分别保存“组是否启用”和“规则是否启用”,执行时取两者的交集。

上图为项目公开的站点管理演示图,域名与请求头值是示例。
这条经验也适用于通知分组、任务暂停和功能配置:临时停用通常不应该抹掉更细的偏好。
点下保存,事情还没结束
界面里看到新值,只说明前端已经接受了编辑。RequestKit 还需要把配置写入本地存储,再把它转换成浏览器真正执行的规则。
这里采用 Chrome 的 declarativeNetRequest:扩展提交声明式规则,由浏览器在请求过程中应用。动态规则会跨浏览器会话保留;已完成的请求不会被事后修改。规则更新后,需要观察新发出的请求。Chrome 官方说明
这也意味着保存存在中间失败状态。例如本地配置写成功了,规则同步却失败,界面和浏览器就可能各自相信不同的事实。
当前实现会尝试恢复之前的配置并重新同步旧规则;恢复失败也有单独的错误状态。它不是数据库事务,不能宣称跨存储和浏览器规则更新绝对原子,但必须让失败变得可见,而不是仍然弹出“保存成功”。保存与恢复逻辑
编辑器打开时,也要记住它在改谁
还有一个容易忽略的场景:打开 A 站点的一条规则开始编辑,外面的视图随后切到 B,最后按下保存。
保存目标应该仍然是 A,而不是提交瞬间界面恰好选中的 B。RequestKit 会记录编辑开始时的目标,并在保存时核对原规则。如果其他窗口已经改过同一份数据,就不能悄悄覆盖。编辑目标与冲突检查
这里最值得复用的并不是某段扩展 API 调用,而是三个问题:修改对象是否明确,用户原来的选择是否保留,执行失败后是否还能理解当前状态。
下一次做一个“小工具”,我仍然会先把这些问题写清楚,再决定界面上需要多少按钮。
可以从 RequestKit 仓库的安装说明 开始体验。配置保存在当前浏览器,没有账号系统;文中实现以 2026 年 9 月 11 日检查的源码为准。
