Skip to content

Latest commit

 

History

163 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

跨域代理助手 - CORS 跨域调试 · API 环境切换 · Mock

简体中文 | English

一条浏览器规则,把 FAT 前端指到 UAT 后端——不改代码、不改后端 CORS、不用重新构建。

License: MIT CI Release Manifest V3 Chrome PRs Welcome 产品站 给仓库点个 Star Chrome Web Store

跨域代理助手配置页规则总览:七条演示规则覆盖 FAT → UAT 通配符重写、注入凭据变量、Mock API、延迟、阻断埋点与 WebSocket 转发,顶部代理总开关与搜索筛选

🛒 从 Chrome 应用商店添加 · 📥 三种安装方式 · ⚡ 一分钟配出第一条规则 · 🌐 产品站 · 💬 交流群

页面连着 FAT,你要的修复只在 UAT。传统做法要么改每个项目的 devServer 代理、要么硬塞一个 token、要么请后端放开 CORS 再发一次版。这里只需要在 Chrome 里加一条规则:匹配 https://fat-api.example.com/*,目标 https://uat-api.example.com。同一套规则还能改写请求头与响应、Mock 数据、注入延迟、阻断请求、转发 WebSocket。

🔒 规则与日志只存本机,无遥测、无自有服务 | 🧪 代理与改写链路有 Vitest 单测覆盖 | 🎨 6 套主题 · 中英双语 | 📖 MIT 开源

目录:它解决的是什么 · 界面预览 · 安装 · 核心优势 · 横向对比 · 工作原理 · 功能 · 使用场景 · 常见问题 · 权限 · 交流与反馈 · 参与贡献


🎯 它解决的是什么

跨环境联调通常要付出三样代价之一:改后端、改每个项目的配置、或者在本地伪造一份构建。这个扩展把它们收敛成浏览器里的一条规则。

不用它 用一条规则
改 devServer 代理表,然后重启本地服务 保存一条通配规则,立刻生效,且对浏览器里所有项目都生效
请后端把来源加进 Access-Control-Allow-Origin 并重新发版 带高级能力的请求由扩展代发,页面侧不触发 CORS 校验
在源码里硬写另一个环境的 token,还得记得改回来 按规则注入请求头,联调完把这条规则关掉
接口还没写好,只能先在前端塞假数据 在规则里 Mock 响应,业务代码一行不动

技术栈:WXT + Vue 3 + TypeScript + Element Plus + Vite,Manifest V3。

📸 界面预览

六张图对应六种日常动作:看全局 → 建规则 → 先验证会不会命中 → 看请求实际发生了什么 → 快捷开关 → 迁移配置。点图可看原图。

规则编辑弹窗:正则匹配模式、重写目标、HTTP 方法、查询参数与请求头覆盖
规则编辑器——匹配 / 重写 / 请求头与响应覆盖 / 条件化 Mock / 延迟 / 阻断 / 重试,一个表单配齐,带实时冲突提示
URL 匹配预演:命中规则、重写后地址与转发通道
URL 匹配预演——粘贴任意地址,实时查看命中规则、重写结果、转发通道与被遮蔽规则
请求日志抽屉:总计与成功失败、两条通道各自的命中统计、原始与代理地址并排
请求日志——最近 500 条,可筛选、复制为 cURL、导出 HAR,含两条通道各自的命中统计
扩展弹窗:总开关、今日请求与快捷入口
弹窗——总开关、今日请求、自动关闭倒计时、当前页命中预演与「为本页创建规则」
导入前预览:预计写入 2 条规则、2 条同键规则将被跳过,并点名不会生效的目标地址
导入与导出——粘贴或选择 JSON 后先「预览变更」:写入几条、哪几条因同名同匹配模式被跳过、哪个目标地址不会生效,导入前就说清楚;同一弹窗还负责导出(分享模式剔除凭据)、cURL / HAR 导入与整套替换前的恢复点
偏好设置弹窗:主题颜色、界面语言、自动关闭代理与凭据变量表,变量真值以圆点遮蔽
凭据变量——token 只在本机存一份,规则里写 {{名称}} 引用,代发那一刻才展开;导出、日志与页面侧脚本都拿不到真值
更多操作细节 · Mock 响应 · 延迟 · 阻断 · 响应改写

Mock 响应——在规则表单里打开 Mock Response,设置状态码(默认 200),选择 Content-Type(JSON / 文本 / HTML / XML),粘贴响应内容。后端接口还没就绪时最实用。

请求延迟——打开 Request Delay,设置毫秒数(0–60000),用来验证加载态、骨架屏与超时处理。

请求阻断——打开 Block Request。命中请求直接收到网络错误,这就是验证异常处理与离线兜底的方式。

响应改写——展开 Response Overrides,可设置状态码与状态行文本、新增或覆盖响应头、按点分路径替换指定 JSON 字段(如 data.token → "mock-token"),或用整段正文直接替换整个响应体(填了它,按字段替换就不再生效)。

更多操作细节 · 拖拽排序 · HAR · cURL · 日志详情

拖拽排序——拖动任意行的 ⠿ 手柄。表格按数组顺序展示,拖拽会同时更新展示顺序与优先级数值。

HAR——导入导出对话框里「导出 HAR」会把后台通道抓到的请求下载为 .har,脱敏与否跟随同一个「分享模式」勾选(默认脱敏);「导入 HAR」会依据录制条目自动创建代理规则(新规则默认停用,确认后自行启用)。

cURL 导入——把 cURL 命令粘贴到「导入 cURL」区域(支持续行符与单双引号),点「解析并创建规则」。扩展会根据请求来源生成通配规则,并把请求头与请求体预填到改写区,确认后保存即生效。

日志详情——点击任意日志行展开详情:请求 URL、请求头、请求体、响应头与文本响应体(JSON 自动格式化;二进制响应体不落盘)、错误信息,以及「复制为 cURL」按钮(按原始请求地址生成)。

📥 安装

需要较新版本的桌面 Google Chrome(Manifest V3)。推荐通过 Chrome Web Store 安装,也可以从源码构建。

A. Chrome Web Store(推荐)

直接访问 Chrome Web Store 添加扩展。

B. GitHub Releases(预构建包)

每个 v* tag 的 Releases 都附带构建好的 zip:

  1. 下载并解压 zip。
  2. 打开 chrome://extensions。
  3. 开启右上角「开发者模式」。
  4. 点「加载已解压的扩展程序」,选中解压出来的目录(含 manifest.json 的那层)。

C. 从源码构建

git clone https://github.com/liaolongdong/cross-origin-proxy
cd cross-origin-proxy
pnpm install
pnpm build

按上面同样三步加载 .output/chrome-mv3。

三种安装方式结果一致:装好后点图标打开代理开关,加一条规则,刷新页面。

一分钟配出第一条规则

  1. 点扩展图标,打开代理开关。

  2. 点弹窗里的规则管理——配置页会带着新建规则表单打开。

  3. 填写规则:

    字段 说明
    匹配类型 通配符(https://fat-api.example.com/*)、前缀 或 正则
    匹配模式 要拦截的 URL 模式
    目标 URL 命中后转发到的地址;留空则不改写地址,仅由扩展按原地址转发
    优先级 数值越小越先匹配
  4. 刷新页面。命中已启用规则的请求会被代理。但像上面这种通配符重写走的是网络层,不会留下逐条请求日志——弹窗右上格「本页 · 近 5 分钟」会显示这个标签页在网络层被命中了多少次,也可以用 URL 匹配预演,或到请求日志里看 DNR 命中统计来确认。

✨ 核心优势

优势 联调时意味着什么
⚡ 快通道上零 JS 只重写 URL 的规则编译成 declarativeNetRequest 重定向,由浏览器网络栈完成转发,每个请求不会跑一段页面侧钩子
🌐 不装本地 CA 也能改写 HTTPS 它运行在浏览器内部:不必安装证书、不必把 DevTools 指到某个代理端口、不动系统级设置
📝 改写的是响应,不只是目的地 状态码与状态行文本、响应头,按点分路径替换单个 JSON 字段(data.token),或整段替换响应体;Mock 还能按 URL / 方法 / 查询参数条件挑选响应体
🔌 覆盖 WebSocket ws:// 与 wss:// 长连接用同一套规则重写,不必另配
🔄 管的是环境,不是一次性改动 环境配置快照把整套规则存成命名快照,在 FAT / UAT / PROD 间一键切换;自动关闭倒计时在你忘记之前把代理关掉
🔒 数据不出本机 规则、日志与环境配置全部留在 chrome.storage.local:无统计埋点、无遥测、无账号、也没有自有服务端
📖 开源且双语 MIT 协议,界面与文档同时提供中英文两版

适合谁

  • 💻 前端 / 客户端开发 — 页面停在 FAT,修复在 UAT:一条规则切过去,不动 devServer、不动源码
  • 🧪 测试工程师 — Mock、延迟、阻断、重试把「等后端造数据」变成自己配一条规则,异常分支也能稳定复现
  • 🔧 全栈 / 后端 — 本地服务起来后,让已部署的前端直接调你这台机器,不必先申请域名与 CORS 白名单
  • 🔁 多环境切换频繁的人 — 命名快照在 FAT / UAT / PRE / PROD 间一键换,不用每次重填一遍规则

🆚 横向对比

⭐ 为本项目。各行结论取自各方案的公开能力,与本仓库方案对比页一致。

关心的事 ⭐ 跨域代理助手 Dev Server 代理 系统级抓包代理 API 客户端 改请求头的扩展
需要后端 / 网关配合改动 ✅ 不需要 ⚠️ 常需要 ✅ 不需要 ✅ 不需要 ✅ 不需要
一次配置对浏览器里所有项目生效 ✅ 是 ❌ 每个项目一份 ✅ 系统级 ❌ 只发自己的请求 ✅ 是
改写响应(状态码 / 响应头 / JSON 字段) ✅ 是 ❌ 否 ✅ 是 ⚠️ Mock 服务 ⚠️ 仅响应头
Mock / 延迟 / 阻断 / 重试 ✅ 含条件化 Mock ❌ 需额外插件 ✅ 是 ✅ 是 ⚠️ 通常只有 Mock
覆盖 WebSocket ✅ 是 ⚠️ 少见 ✅ 是 ❌ 否 ❌ 否
读取 HTTPS 需要装本机 CA 证书 ✅ 不需要 ✅ 不需要 ❌ 需要 ✅ 不需要 ✅ 不需要
覆盖非浏览器流量(手机 App、桌面、服务端进程) ❌ 只在浏览器内 ❌ 否 ✅ 能 ⚠️ 只覆盖它自己发的 ❌ 否
无需浏览器即可在 CI 里跑 ❌ 否 ✅ 是 ✅ 是 ✅ 是(CLI runner) ❌ 否

✅ 开箱即用 · ⚠️ 有条件或需额外配置 · ❌ 该方案做不到。

什么时候别用它:需要覆盖手机 App 或桌面程序的流量(走系统级抓包代理)、需要一份能被 review 且全团队共用的配置(写进仓库的 devServer 代理或应用配置)、接口本身还不存在且需要先跟后端约定形状(API 客户端里那份请求才是可分享的产物)。六条判据与理由在对比页写全了:中文 · English。

🧭 工作原理

每条启用的规则在每次配置同步时按其自身字段重新判定一次,判定结果并不存储在规则上。只做 URL 重写的规则会编译成 declarativeNetRequest 动态规则,交给浏览器网络栈处理,单个请求零 JS 开销;能力更全的规则走后台通道。代理开关管住两条通道:关掉它时网络层规则同样会被卸载,不会出现「以为关了、其实还在重定向」。

flowchart TD
    A["页面发起请求<br/>fetch · XMLHttpRequest · WebSocket"] --> B{"命中一条启用中的规则?<br/>优先级数值小的先命中"}
    B -->|都没命中| C["原样放行"]
    B -->|命中| D{"这条规则只做 URL 重写?"}
    D -->|是 · 简单规则| E["declarativeNetRequest 重定向<br/>浏览器网络层完成转发,单请求零 JS 开销"]
    D -->|否 · 复杂规则| F["页面拦截器(MAIN world)<br/>改写头 / 体 / 响应 · Mock · 延迟 · 阻断 · 重试 · WebSocket"]
    F --> G["桥接(ISOLATED world)<br/>chrome.runtime 消息"]
    G --> H["后台服务线程代发请求"]
    H --> I["响应回传页面"]
Loading

规则一旦带上下列任一项就不再是「简单规则」:请求头改写、请求体改写、响应改写、Mock、延迟、阻断、重试、HTTP 方法过滤、查询参数注入、携带 Cookie、ws:///wss:// 目标、不以 * 结尾的通配符、目标地址留空。这些条件不是因为实现偷懒,而是网络层确实无法表达,详见 utils/urlMatcher.ts。

正则规则要覆盖整个 URL。 通配符与前缀的重写在两条通道上语义一致,正则却不一定:后台通道只替换模式匹配到的那一段,未匹配的部分原样保留;网络层则用替换串整体替换掉整个 URL。所以 ^https://fat\.example\.com/api/(.*) 配 https://uat.example.com/$1 两边结果相同,而 ^https://fat\.example\.com/api 这种不完整模式在后台通道会留下 /users,在网络层会直接丢掉。用 ^ 锚定、用 (.*)$ 捕获结尾,两者就一致;具体某条地址走哪条通道,URL 匹配预演会告诉你。还有一处刻意保留的外观差异:通配符末尾的 * 什么都没捕到时(请求正好是 https://fat.example.com/),网络层给出 https://uat.example.com/,后台通道给出 https://uat.example.com——两者指向的是同一个资源。

关于 CORS,说准确一点。 后台通道的请求由扩展(持有站点权限)发出,页面拿到的是扩展构造的响应,因此不受页面 CORS 校验约束。而纯网络层重定向,浏览器仍会校验重定向后响应的 Access-Control-Allow-Origin。如果目标环境没放行你的来源,给规则加上任意一项能力(最省事的是加个响应头改写),它就切到后台通道。

整页与 iframe 同等对待。 内容脚本注入到页面的全部 frame,所以复杂规则在 iframe 里同样生效——不必因为请求发自子框架就退回原生请求。弹窗里那一行「页面自报」把各 frame 的数合起来给一个结论,交叉校验则按 frame 各记一本账:某个 frame 少报不会连累其它 frame 的读数。

这一页收到最新配置了吗。 复杂规则靠把新配置推给已打开的页面实时生效,而有些页面天生收不到那次推送:它是在扩展安装、更新或重载之前就打开的(那个文档里根本没有内容脚本),或者该站点被禁用了扩展。前者刷新这一页就好,后者得先在 Chrome 的扩展菜单里为该站点重新开启,而此前界面上却没有这句话,用户手里只剩「我改了规则,可这个页没反应」。现在推送没送达的页面会在弹窗得到一句「此页尚未收到最新配置,刷新这一页通常可恢复」,悬停进一步说明是哪两种原因、各自的修法是什么。这句只说它有把握的事:非 http(s) 页、正在加载的文档、以及从没记过「没送达」的页面统统保持沉默,页面自己拉到配置之后这句话也会消失,扩展重启后这笔账从零开始而不是凭空冒出一堆警告。它是标签页粒度的一个结论——一屏一句,不逐 frame 追究。

兜底行为。 拦截失败时页面会回退到原生 fetch / XMLHttpRequest / WebSocket,请求照常发出,不会因为扩展异常而中断。同步 XHR(open() 第三参传 false)与 FormData / Blob / ArrayBuffer 这类非字符串请求体同样回退原生——代理要跨上下文往返,拿不到「send() 返回时结果已就绪」这个契约,异步化会让页面读到一个空响应。阻断规则是唯一的例外——被阻断的请求绝不回退发出。

📋 功能

🔀 代理与请求改写

  • 规则化 URL 重写——按通配符、前缀、正则匹配后转发到目标环境
  • 请求头改写——按规则注入或替换请求头(例如目标环境的鉴权 token)
  • 携带 Cookie——默认不带目标站的 Cookie;按规则开启后由扩展以 credentials: 'include' 代发,让目标环境认得你在它那里的会话
  • 请求体改写——用自定义内容替换原始请求体
  • 响应改写——改写响应状态码与状态行文本、响应头,按点分路径替换 JSON 字段(如 data.token),或整段替换响应体(非空时优先于按字段替换)
  • Mock 响应——不访问任何服务,直接返回自定义 JSON / 文本 / HTML / XML
  • 条件化 Mock——可挂多组条件(URL 正则、HTTP 方法、查询参数),首个命中的条件决定响应体、状态码与 Content-Type
  • 延迟注入——0–60000 毫秒人工延迟,用来验证加载态与超时分支
  • 请求阻断——命中即网络错误,用来验证异常处理与离线兜底
  • 失败重试——按规则开启的开关,在网络错误、5xx 响应或单次 30 秒超时之后追加 1–5 次尝试,间隔 100–30000 毫秒(默认 1000)。页面取消会传到后台:被代理的 fetch / XHR 请求被页面放弃时(AbortController 触发、xhr.abort()、或页面自己设的 xhr.timeout 到期),扩展会掐断它正在跑的那笔上游请求并停止后续重试,日志按 Cancelled by page 记,与超时分开(WebSocket 由页面直连,扩展侧没有代发请求可取消)
  • HTTP 方法过滤——把规则限定在指定方法(GET/POST/PUT…),留空表示任意方法
  • 查询参数注入——在最终代理地址上追加或覆盖参数(__env=uat、灰度标识),不必整段重写 URL
  • 凭据变量 {{名称}}——请求头与查询参数的值都可以写成 {{UAT_TOKEN}},真值单独存在「设置 → 凭据变量」里:规则本身、导出的配置文件、下发给页面的配置都只带着这个字面量走,换出真值发生在扩展代发请求的最后一刻,本地日志记的也是未展开形态(WebSocket 规则的查询参数由页面侧拼接,那一侧读不到变量表,所以表单会当场拒绝这种组合而不是让它静默失效)
  • WebSocket 代理——按 URL 重写转发 ws:// / wss:// 连接,由页面拦截器处理;长连接上生效的只有地址重写、查询参数注入与阻断,请求头 / 请求体 / 响应改写、Mock、延迟、重试、携带 Cookie 都不适用(徽标悬停会说明这一点)

🧰 规则管理

  • 可视化表单新增 / 编辑 / 复制 / 删除
  • 快速模板在规则为空时的引导区提供,覆盖常见写法(通配符 API 代理、前缀路径、鉴权头、自定义头覆盖)
  • 删除可撤销——单条与批量删除共用同一个 5 秒窗口,窗口内点「撤销」零成本放回原位(不写存储),窗口结束才真正落盘;落盘失败会把规则放回列表并明确报错,不会出现「界面说已删除、存储里还在代理」
  • 拖拽排序优先级(拖动 ⠿ 手柄)
  • 能力徽标一眼看清规则做了什么:H 请求头 · C 携带 Cookie · B 请求体 · R 响应 · M Mock · D 延迟 · X 阻断 · Re 重试 · WS WebSocket
  • 单条与批量启用 / 禁用
  • 批量迁移目标域名——选中多条规则做查找替换,带逐条变更预览
  • 关键字搜索覆盖名称、匹配模式与目标地址,另可按状态和匹配类型筛选;勾选跨筛选保留,批量操作只作用于当前仍存在的规则
  • 「未生效」标记——正则规则若用了 RE2 不支持的语法(环视、反向引用),或目标地址引用了越界的捕获组,浏览器根本不会应用它;这类规则在列表里标红,悬停给出原因与改法
  • 遮蔽冲突提示——当被同模式更高优先级规则遮蔽时,编辑中即时提醒,避免写下一条永远不会命中的规则
  • 正则捕获组对照——编辑正则规则时,表单把模式里的捕获组与目标地址里的 $n 引用逐条列出来对照,标出编号越界的、以及超过 \9 的(网络层的替换串按单个数字读,编号 10 起只有转发通道拿得到);判据与上面那个「未生效」标记同源,只提示、不拦保存,因此导入进来的规则照样能改名字与优先级
  • 命中数列分两格——网络层那一格读的是近 5 分钟窗口,后台通道那一格是自配置变更起的内存计数(后台工作线程被回收后从 0 重新开始),两者口径不同、不再相加成一个数;每格只代表自己那条通道,读不到、或这条规则根本不走该通道时显示「—」而不是 0,「没有生效的网络层规则」「配额用尽」与「不适用」是三句不同的话

🔍 日志与调试

  • 请求日志面板:方法、状态、耗时,以及两条通道各自的命中统计(DNR 近 5 分钟、后台服务线程自配置变更起,后者为内存计数,后台工作线程被回收后从 0 重新开始)。DNR 的读取接口有配额限制(约 20 次 / 10 分钟),所以计数是按需采样的:计数读不到上一次结果时会标出「网络层统计可能有延迟」,弹窗里那一格则按当前标签页单独统计
  • 日志详情:可看请求与响应的头与文本 body(二进制响应体不落盘;单条正文超过 32K 字符会截断并标注原始长度),JSON 自动格式化;Authorization / Cookie 一类会带出会话的头,其值默认打码(长值留尾 4 位,够分辨是哪一把),详情面板右上角的「显示凭据原值」不落存储、关掉抽屉即收回
  • 任意一条日志复制为 cURL(按原始请求地址),也可直接由这条请求创建规则
  • 按方法(GET / POST / PUT / DELETE / PATCH / OPTIONS / HEAD)、状态类别(2xx / 4xx / 5xx)、规则、URL 关键字筛选
  • 顶栏URL 匹配预演:输入任意地址(可再选 HTTP 方法),实时看到命中规则、重写后的地址、转发通道,以及还有哪些规则同样命中、但被它遮蔽;走网络层通道时会说明该通道仍受 CORS 约束

📦 导入导出与环境

  • 配置以 JSON 导出,分享模式默认开启:自动剔除 Authorization、Cookie 一类请求头/响应头与 token 类查询参数,导出提示会报出移除条数;需要本机全量备份时取消勾选即可原样导出。用了凭据变量的规则更省事——真值从来不在配置文件里,导出的是 {{UAT_TOKEN}} 这个引用本身,取消勾选也不会带出去
  • 导入支持覆盖或合并两种模式,两者都受 200 条上限约束。写入前可以先预览这个文件:预计新增几条、哪些同名同模式的旧规则会被保留(合并键是「规则名 + 匹配模式」,所以只改了目标地址的同类规则算新增,不是更新),以及文件内部自身重复的条目;预览与真正写入走的是同一份判据,两处的数不会互相打脸。比当前版本更高的配置文件直接拒绝,不做部分读取。失败时输入原样保留、弹窗不关,改完可直接重试
  • 配置恢复点:覆盖导入、加载环境快照、真正删掉了东西的批量删除这三类「整套替换」会各自留下被替换掉的那份规则集(最近 5 份,列在「设置 → 配置恢复点」),一键回退,回退本身也同样留下一份。恢复点里只有规则快照(凭据仍是 {{名称}} 引用),且回退只换规则集、不动总开关
  • HAR 1.2 导出抓到的请求,与配置导出共用同一个分享模式勾选(默认开启):脱敏时逐条剔除请求/响应头里的 Authorization、Cookie 一类凭据,正文与 URL 照旧保留(URL 上带的 token 需要你自行处理);取消勾选即全量导出;导入 HAR 会依据录制请求自动生成代理规则(新规则默认停用,确认后自行启用)
  • cURL 导入——粘贴 DevTools 的 Copy as cURL 结果即可解析并预填规则
  • 环境配置快照——把当前规则集存成命名快照,在 FAT / UAT / PROD 间一键切换:弹窗里点「环境配置」直接列出已存的快照,点一行、再确认一次就整套换过去(确认那句话会点名两件事——这是整套替换,且代理总开关会被打开;当前配置先记为一份恢复点)。一份快照都还没存、或这次没读到列表时,这颗卡照旧跳到配置页的管理弹窗,不会把「没读到」说成「你没存」
  • 自动关闭倒计时(基于 chrome.alarms,后台脚本重启后仍然有效)与状态徽章;档位(从不 / 30 分钟 / 1 / 2 / 4 小时)在弹窗和设置页都能改

🎨 界面

  • 弹窗快捷面板:总开关、经扩展请求数(只统计后台通道)、本页近 5 分钟的网络层命中数、最近请求、自动关闭档位与倒计时、本页地址命中预演(并标出浏览器不会应用的网络层规则)、「为当前页创建规则」——点击后优先列出这一页正在调用的接口来源(读的是页面自己的资源计时记录,只取来源与请求次数;问不到就退回按页面地址预填),选定一条即预填新规则,以及**「环境配置」就地切快照**(点开列快照,确认那一步在弹窗里做完,不引对话框模块)
  • 弹窗数据行下方按需出现一行本页拦截活动的「页面自报」(这一页的地址命中了走后台通道的规则、或已经有过读数时才画出来):一句话点出这一页被拦到多少请求、其中多少已交给后台代发(有回退时改说其中多少回退成了原生请求,没有回退但有超时时的第二个数是「交给后台后没等到响应」多少),有读数时悬停展开可见全四个数与上报时刻,并写明同一请求可同时计入多项、四个数不能相加;四个数按本页本次文档累计,导航即归零。它补上了另外三条证据都看不见的那一段——复杂规则一次没拦到时,「经扩展请求 0」与「这个页面本来没请求」看起来一模一样,而回退原生请求与代发超时原本只在控制台留一行日志。回退数大于 0 会点名「这一页有请求没有走代理」,优先级高于超时那句(一句话只放得下最该先知道的那件事)。这四个数由页面自己上报,可被这一页上的脚本伪造(改不动别的标签页),所以只做诊断线索、不参与任何判定,措辞也始终写「页面自报」
  • 弹窗另有一行**「此页尚未收到最新配置,刷新这一页通常可恢复」:复杂规则靠把新配置推给已打开的页面实时生效,而这一行只在后台确实记下了「这一页没接到那次推送」时出现(且总开关开启、本页可代理、这次真的读到了账)。悬停点名两种原因与各自的修法——页面是在扩展安装 / 更新 / 重载之前**打开的(刷新即可),或该站点禁用了扩展(要在 Chrome 的扩展菜单里重新开启)。这笔账只存内存、只记已知失败,非 http(s) 页与正在加载的文档都不参与,页面自己重新拉到配置时会当场销账,所以「不知道」不会画成「有问题」,扩展重启后也不会凭空冒出一堆警告
  • 中英文界面,6 套主题 + 浅色 / 深色 / 跟随系统
  • 凭据变量表在设置弹窗里:命名存真值(上限 50 条,值默认以密码框画出来),每把标出「被 N 条规则使用」,删除在用的变量要二次确认;规则还在引用而表里已没有的名字会列成一行孤儿告警,而不是等到请求失败才发现
  • 快捷键:⌘+⇧+P 切换代理(Chrome 级命令);配置页内 N 新建规则、/ 或 ⌘+F 聚焦搜索、Esc 关闭最上层弹窗。N 是单键(同 Gmail 风格),因为 ⌘+N 被浏览器保留、页面捕获不到
  • 读数变化看得见:保存或复制规则后那一行会滚进视野并刷两拍主色(200 条时新行落在表格最底部,成功提示与「我那条呢」之间原先隔着一次手动滚动);「活跃规则」那一格与规则列表的命中数只在数字真的换了那一拍给一次极轻的回执,所以周期性的状态刷新是安静的;「浏览器不会应用该规则」那枚红标首次出现时向外散一圈危险色,滚动时长表格里也不会看漏。减弱动效档下这些一律不播,连滚动都是直接落位

🚀 使用场景

场景 怎么配
在 FAT 页面验证只在 UAT 的改动 API 前缀通配重写到 UAT 域名
后端还没开发完,先把前端做完 Mock 响应,自定义 body 与状态码
验证加载态、骨架屏与超时 对指定接口注入 3000–60000 毫秒延迟
验证 500 与离线兜底 UI 阻断请求,或改写响应状态码
走灰度分支或 A/B 策略 查询参数注入
联调实时推送等长连接 WebSocket 重写
只把写操作打到测试后端 方法过滤,仅放行 POST / PUT / DELETE
把同一套配置交给同事 导出 JSON(默认剔除凭据)或 HAR 规则集

❓ 常见问题

它能绕过 CORS 吗?

后台通道的规则可以:请求由持有站点权限的扩展发出,页面拿到的是扩展构造的响应,页面侧 CORS 校验不会触发。纯 URL 重写会被编译成网络层重定向,浏览器仍会校验 Access-Control-Allow-Origin。给规则加上任意一项能力,它就切到后台通道。

所有网站都能用吗?

内容脚本注入全部 http / https 页面,规则按请求 URL 匹配,内网系统、localhost 开发服务、预发域名都适用。chrome:// 页面、应用商店页与其他扩展页面是 Chrome 对所有扩展的统一限制,无法注入。

改了规则,可这一页没反应?

常常不是规则的问题,而是这一页没收到新配置:它是在扩展安装、更新或重载之前打开的(那个文档里根本没有内容脚本),或者该站点被禁用了扩展。前者刷新页面即可,后者要在 Chrome 的扩展菜单里对该站点重新开启。推送确实没送达时弹窗会直接写出这句话,悬停给出两种原因与各自的修法;读不到账它就什么都不说,不会把「不知道」画成「有问题」。规则本身用「URL 匹配预演」核对:这条地址命中哪条规则、走哪条通道、有没有被更宽的规则遮蔽。

数据会被上传吗?

不会。规则、日志、环境配置与偏好全部留在本机 chrome.storage.local,没有统计埋点,也不连接任何自有服务,唯一的网络流量就是你要求代理的 API 流量。详见隐私政策(中英双语同页)。

一个只涉及本机的提醒:请求日志会存下被代理的请求头与请求体,里面可能包含 token;数据不出机器,但截图或粘贴日志详情之前请先清一遍——日志详情里 Authorization / Cookie 这类头的值已经默认打码(要对着尾号排障时再手动「显示凭据原值」,关掉抽屉就收回)。配置导出与 HAR 导出默认都开着「分享模式」,自动剔除 Authorization、Cookie 等头,配置导出还会剔掉 token 类查询参数覆盖——需要全量备份时取消勾选,那两份文件就和日志一样敏感。规则里的凭据位点改用 {{名称}} 引用「设置 → 凭据变量」之后,真值只在那一处落地:导出的配置文件与快照里从头到尾没有它,取消分享模式也不会带出去。

为什么我的规则走的是慢通道?

因为它带了网络层无法表达的能力;也可能是通配符不以 * 结尾、或目标地址留空——这两种情况若强行编译成重定向会静默改变结果。用 URL 匹配预演就能看到每条地址实际走的通道。

有哪些限制?

规则 200 条、日志最近 500 条(单条正文最多 32K 字符,超出会截断并标注原始长度;URL、方法、规则名与头值最多 8K 字符、每份头表最多 64 条,整份日志另有 4M 字符总预算)、请求体上限 10MB、延迟 0–60000 毫秒;导入文件体积上限 2MB、HAR 条目上限 5000 条,超限直接拒绝并说明原因,不做部分读取;Mock 与响应改写的状态码钳制在 200–599,否则前端构造不出合法的 Response。

支持 Firefox 或 Edge 吗?

按 Chrome(MV3)构建与验证。Edge 兼容 Chromium 扩展,同一份构建通常可用;Firefox 因 declarativeNetRequest 支持差异,目前不作为支持目标。

🔐 权限

权限 用途
storage 本地保存规则、日志、环境配置与偏好
declarativeNetRequest 为简单规则安装网络层重定向,做到单请求零 JS 开销
declarativeNetRequestFeedback 读取规则命中情况,用于日志抽屉的命中统计
alarms 后台脚本保活与自动关闭倒计时
<all_urls>(站点权限) 代理必须能在任意前端来源上工作,目标域名由你自己配

每项权限面向商店审核的说明文案在 CHROMEWEBSTORE.md。

🤝 参与贡献

技术栈为 WXT + Vue 3 + TypeScript + Element Plus(Manifest V3),需要 Node.js 20+ 与 pnpm 10;pnpm dev 起 HMR 开发、pnpm build 产出 .output/chrome-mv3、pnpm test 跑单测。小修复也欢迎——完整命令清单、目录结构、CI 与发版约定请先读 CONTRIBUTING.md,商店发布流程见 RELEASING.md,GitHub 仓库设置清单见 GITHUB.md。

💬 交流与反馈

规则怎么写、代理为什么没生效、某个环境下的坑怎么绕,都可以在群里问,作者本人常驻群里。

微信交流群二维码

扫码添加作者微信(微信号:lld_1025),好友请求备注 cxp(cross→cx、proxy→p 的缩写),通过后拉进交流群。

🧩 我的其它插件

  • ⭐ 账号密码管理助手 · Account Password Helper:同一作者的另一款 Manifest V3 扩展,本地优先的开源密码管理器——一键登录连登录按钮一起点,按精确域名隔离 dev / test / staging / prod,内置 TOTP 两步验证与离线安全体检。它处理「这个环境我是谁」,本扩展处理「这个环境请求打到哪」,联调时常常一起开着。产品页 · Chrome 应用商店
  • 文件格式任意转换助手 · Transfer Any File:同一作者的另一款 Manifest V3 扩展,14 种格式在浏览器里互转、一个字节也不上传的离线文件转换器——Markdown、Word、PDF、Excel、CSV、JSON、HTML 与图片在自己电脑上完成转换,支持批量混合格式、自动多步链路、预览与内联编辑、ZIP 打包。无账号、无上传、无网络请求。产品页

📄 许可证

MIT · Copyright (c) 2026 Better


如果它帮你省掉了一次后端发版,点个 Star 让更多前端同学看到它:

给仓库点个 Star   产品说明页


产品站:中文 · English · 方案对比 · 隐私政策 · 机器可读:llms.txt · llms-full.txt

About

Chrome extension: point a FAT frontend at a UAT backend with one rule. Proxies API requests cross-origin - rewrite URL/headers/responses, mock, delay, block, retry, WebSocket. No backend CORS changes. 跨域代理助手 · 环境切换

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages