基于瀏覽器擴(kuò)展 API Mock 工具開(kāi)發(fā)探索
一、前言
二、瀏覽器插件介紹
1. 什么是瀏覽器插件?
2. Manifest V3 架構(gòu)
3. 核心配置差異示例
三、Mock 插件實(shí)現(xiàn)的基本原理
1. 請(qǐng)求攔截的核心原理
2. 腳本注入
四、整體實(shí)現(xiàn)架構(gòu)與流程
1. 項(xiàng)目結(jié)構(gòu)設(shè)計(jì)
2. 相關(guān)功能介紹
3. 整體流程
五、總結(jié)與收獲
六、未來(lái)展望
一、前 言
在日常開(kāi)發(fā)過(guò)程中,偶爾會(huì)遇到后端接口未完成或者某個(gè)環(huán)境出現(xiàn)問(wèn)題需要根據(jù)接口返回來(lái)復(fù)現(xiàn)等等場(chǎng)景。剛好最近在學(xué)習(xí)瀏覽器插件的相關(guān)知識(shí),并在此背景下開(kāi)發(fā)了一款基于瀏覽器插件的 Mock 工具。該工具專注于 API 請(qǐng)求攔截和數(shù)據(jù)模擬,旨在幫助開(kāi)發(fā)者提升開(kāi)發(fā)效率,能夠解決一些問(wèn)題。
二、瀏覽器插件介紹
什么是瀏覽器插件
瀏覽器插件(Extensions 或 Add-ons)是一類運(yùn)行于瀏覽器進(jìn)程中的輕量級(jí)功能增強(qiáng)模塊,其核心價(jià)值在于通過(guò)標(biāo)準(zhǔn)化接口實(shí)現(xiàn)對(duì)瀏覽器內(nèi)核能力的深度整合與定制。根據(jù) Mozilla 開(kāi)發(fā)者文檔定義,插件本質(zhì)上是“能夠修改和增強(qiáng)瀏覽器能力的應(yīng)用程序”,F(xiàn)irefox、Chrome 等主流瀏覽器均采用 WebExtensions API 這一跨瀏覽器技術(shù)構(gòu)建插件生態(tài)。與網(wǎng)頁(yè)應(yīng)用(Web App)需依賴瀏覽器標(biāo)簽頁(yè)運(yùn)行、原生應(yīng)用(Native App)需獨(dú)立安裝的特性不同,插件以輕量化部署為顯著特征——無(wú)需復(fù)雜設(shè)置即可直接在瀏覽器環(huán)境內(nèi)運(yùn)行,同時(shí)具備標(biāo)簽控制、網(wǎng)絡(luò)請(qǐng)求攔截、本地存儲(chǔ)訪問(wèn)等網(wǎng)頁(yè)應(yīng)用無(wú)法實(shí)現(xiàn)的底層能力。
Manifest V3 架構(gòu)
Manifest V3 對(duì)瀏覽器插件的底層架構(gòu)進(jìn)行了顛覆性重構(gòu),主要體現(xiàn)在背景執(zhí)行機(jī)制、網(wǎng)絡(luò)請(qǐng)求控制和代碼安全模型三個(gè)核心維度。以下從技術(shù)實(shí)現(xiàn)與設(shè)計(jì)動(dòng)機(jī)角度進(jìn)行全面對(duì)比:
圖片
關(guān)鍵架構(gòu)變革:V3 采用"靜態(tài)聲明+內(nèi)核級(jí)處理"模式替代 V2 的"動(dòng)態(tài)腳本+插件自主控制"模式,通過(guò)瀏覽器內(nèi)核直接介入關(guān)鍵流程(如網(wǎng)絡(luò)攔截),在性能與安全性之間取得平衡。
圖片
核心配置差異示例
背景執(zhí)行模塊配置
// V2 持久化背景頁(yè)配置"
background": {
"scripts": ["background.js"],
"persistent": true
}
// V3 Service Worker 配置
"background": {
"service_worker": "background.js",
"type": "module"
}網(wǎng)絡(luò)請(qǐng)求規(guī)則配置
V3 需在 Manifest 中聲明 DNR 權(quán)限及規(guī)則文件:
// V3 declarativeNetRequest 配置
"permissions": ["declarativeNetRequest"],
"host_permissions": ["<all_urls>"],
"declarative_net_request": {
"rule_resources": [
{"id": "ruleset_1","enabled": true,"path": "rules.json" }
]
}三、Mock 插件實(shí)現(xiàn)的基本原理
請(qǐng)求攔截的核心原理
由于 Manifest V3 移除了webRequest API 的阻塞能力,declarativeNetRequest又無(wú)法重定向到自定義數(shù)據(jù),于是方案上選擇的是在頁(yè)面上下文中重寫原生 API,目前重寫了fetch跟XMLHttpRequest。
// injected.js - 在頁(yè)面環(huán)境中重寫fetch
const originalFetch = window.fetch;
window.fetch = async function(url, options = {}) {
// 1. 發(fā)送攔截請(qǐng)求到content script
const response = await sendMockRequest(url, options);
// 2. 如果有匹配的Mock規(guī)則,返回Mock數(shù)據(jù)
if (response.shouldMock) {
return new Response(
JSON.stringify(response.mockData),
{
status: response.status,
headers: response.headers
}
);
}
// 3. 否則執(zhí)行原始請(qǐng)求
return originalFetch.call(this, url, options);
};腳本注入
通過(guò)多重注入策略 + 動(dòng)態(tài)檢測(cè)的方式實(shí)現(xiàn), 直接引入會(huì)觸發(fā) Content Security Policy 阻止內(nèi)聯(lián)腳本執(zhí)行。
// content.js
async function injectScript() {
// 策略1: 內(nèi)聯(lián)腳本注入
try {
await injectInlineScript();
if (await checkScriptActivation()) return;
} catch (e) {
console.warn('內(nèi)聯(lián)注入失敗:', e);
}
// 策略2: 外部腳本注入
try {
await injectExternalScript();
if (await checkScriptActivation()) return;
} catch (e) {
console.warn('外部注入失敗:', e);
}
// 策略3: 最簡(jiǎn)單注入方式
await attemptSimpleInjection();
}四、整體實(shí)現(xiàn)架構(gòu)與流程
項(xiàng)目結(jié)構(gòu)設(shè)計(jì)
chrome-mock/
├── build-script/ # rollup 進(jìn)行構(gòu)建
├── static/ # 靜態(tài)文件引入,如mockjs
├── debug/ # 本地調(diào)試相關(guān)的頁(yè)面
├── manifest.json # 插件配置
├── background.js # 核心邏輯處理
├── content.js # 腳本注入和消息中轉(zhuǎn)
├── injected.js # 請(qǐng)求攔截實(shí)現(xiàn)
├── options.html # 管理界面
├── options.js # 管理界面邏輯
├── options.css # 管理界面樣式
├── popup.html # 彈窗界面
├── popup.js # 彈窗邏輯
├── popup.css # 彈窗樣式
└── icons/ # 圖標(biāo)資源相關(guān)功能介紹
創(chuàng)建 Mock 規(guī)則
創(chuàng)建 Mock 規(guī)則提供了多種方式:
- 如果是快速聯(lián)調(diào)的場(chǎng)景,可以用得物API管理平臺(tái)導(dǎo)入的方式。
- 在排查某個(gè)環(huán)境問(wèn)題,需要根據(jù)服務(wù)端接口返回?cái)?shù)據(jù)復(fù)現(xiàn)的時(shí)候,可以通過(guò)在管理規(guī)則頁(yè)面手動(dòng)新建。
方法一:快捷操作彈窗配置
- 打開(kāi) Mock 管理頁(yè)面
點(diǎn)擊瀏覽器工具欄中的 Mock Frog 圖標(biāo);
選擇"管理規(guī)則"或直接訪問(wèn)擴(kuò)展選項(xiàng)頁(yè)。
- 添加新規(guī)則
圖片
方式一:復(fù)制粘貼得物API管理平臺(tái)地址,點(diǎn)擊導(dǎo)入,自動(dòng)生成。這個(gè)彈窗比較小適合自動(dòng)導(dǎo)入的場(chǎng)景,也可以點(diǎn)擊上面 popup 的管理規(guī)則再進(jìn)行操作。
如:https:/apiManage.test.com/project/interface?id=3xxxx&projectId=5xxxx
圖片
本地調(diào)用可能會(huì)有代理增加了前綴,系統(tǒng)會(huì)自動(dòng)在路徑前添加通配符 *
方式二:復(fù)制接口地址到匹配 URL 輸入框中自行配置數(shù)據(jù),這一步建議到管理規(guī)則中才施展的開(kāi)。
支持根據(jù)接口平臺(tái)的 JSON Schema 生成對(duì)應(yīng)類型的 Mock 數(shù)據(jù)。
Mock 效果演示:

方法二:管理規(guī)則頁(yè)配置
由于 popup 界面大小有限,點(diǎn)擊其他區(qū)域彈窗也會(huì)關(guān)閉,提供了一個(gè)比較詳細(xì)的管理頁(yè)可以修改添加規(guī)則。
規(guī)則列表:
圖片
新建 Mock 規(guī)則:
圖片
頁(yè)面白名單管理
作用:針對(duì)所有頁(yè)面都進(jìn)行攔截可能會(huì)導(dǎo)致頁(yè)面卡頓,影響整體性能,于是增加了白名單控制,控制 Mock 功能在哪些場(chǎng)景下才生效。同時(shí)也提供了全局生效模式,方便快速操作。
使用方法:
- 開(kāi)啟白名單功能
進(jìn)入擴(kuò)展設(shè)置頁(yè)面
找到"頁(yè)面白名單"配置
啟用"使用頁(yè)面白名單"
- 添加白名單域名
支持格式:
- http://localhost:3000 # 完整URL
- *.example.com # 通配符域名
- dev.company.com # 具體域名
- http://dev.company.com # 帶協(xié)議的域名
圖片
請(qǐng)求日志
作用:記錄所有 Mock 請(qǐng)求的詳細(xì)信息,便于調(diào)試。
圖片
整體流程
圖片
圖片
五、總結(jié)與收獲
本次插件開(kāi)發(fā)過(guò)程中,探索了瀏覽器擴(kuò)展插件的能力,學(xué)習(xí)了 Manifest V3 的新知識(shí),掌握了瀏覽器插件開(kāi)發(fā)相關(guān)技術(shù)點(diǎn)。隨之而來(lái)帶來(lái)的思考便是在 AI 的浪潮下,瀏覽器插件是否能有更多的可能。
另外,本次很多功能點(diǎn)的實(shí)現(xiàn)也依賴了 Cursor,探索瀏覽器插件的同時(shí)也深入的學(xué)習(xí)了Cursor的應(yīng)用,感受到了Cursor從 0 到 1 搭建過(guò)程中的速度和效率。但是在后續(xù)需要對(duì)功能點(diǎn)進(jìn)行改造時(shí),使用效率并不是高,如何建立規(guī)則和組織話術(shù),讓 AI 更加規(guī)范、高效地輔助開(kāi)發(fā)是一個(gè)值得深思的問(wèn)題,當(dāng)然通過(guò) rules 是能夠解決大部分問(wèn)題。
六、未來(lái)展望
功能升級(jí):在復(fù)雜業(yè)務(wù)場(chǎng)景中,往往需要Mock的接口都比較多。如果能監(jiān)聽(tīng)頁(yè)面所有請(qǐng)求,然后提供通過(guò)選中某個(gè)歷史請(qǐng)求即可Mock接口的方式,就能快速實(shí)現(xiàn)接口的Mock。
能力拓展:探索在瀏覽器插件上結(jié)合 AI 能力的應(yīng)用,基于規(guī)則跟用戶的要求更快速的生成 Mock 數(shù)據(jù)。























