前兩週我做了一個零侵入的介面 Mock 插件。還寫了篇掘金文章記錄了一下:juejin.cn/post/7570984257666056238
此前用 Popup 彈窗做聯調,窗小、易誤關、操作繁瑣;
於是我重構為 Sidebar 常駐側欄:規則隨時可見,刷新也不丟。
現在用起來爽多了,前端開發不用乾等後端,自己就能把頁面跑起來。
下文附安裝與使用指南,歡迎試用與反饋。
如果你現在還在用 Popup 彈窗做 Mock,或者還在一個字一個字敲 JSON,真心建議試試 Sidebar + AI 這套,用完你就知道什麼叫"真香"。
持續優化中,歡迎反饋與建議建設中: 調試與管理:匯入匯出、規則分組、Network 面板標識等;性能與匹配體驗持續優化,歡迎反饋注:支持攔截ajax和fetch請求
打開代碼倉庫,按以下方操作下載插件包。安裝包為 zip,請先解壓。
下載與解壓
參考示意圖:
chrome://extensions/參考示意圖:
gitee 倉庫鏈接的同理,在倉庫頁點擊“發行版(Release)”, 進入最新版本頁面,下載插件包即可
AI 前置準備
sk-9fa67c84581d4f67b61039ff8b199baa示例:
DeepSeek 官網申請key示例:
| 特性 | Popup | Sidebar |
|---|---|---|
| 顯示空間 | 小(~400x600px) | 大(可調整寬度) |
| 操作便捷性 | 點擊外部就關閉 | 固定顯示,不怕誤觸 |
| 與頁面交互 | 互斥 | 可同時顯示 |
| 數據持久化 | 關閉即丟失 | 刷新頁面也保留 |
這塊就兩件事:
只要一句話就夠:
效果圖:
或者直接貼 數據的類型:
interface User {
id: number;
name: string;
age: number;
email: string;
}
效果圖:
目的:把帶佔位符的路徑,轉成更穩的正則,方便在開發態攔截請求
常用示例:
效果圖:
這塊很直觀,給你三種編輯入口,改完就是生效:
效果圖:
設定延時 3 秒,模擬慢介面:
演示效果圖:
一鍵切換不同狀態碼:
效果圖:
配置文件:
{
"manifest_version": 3,
"name": "AI Mock",
"version": "2.0.0",
"side_panel": {
"default_path": "sidepanel.html"
},
"permissions": [
"sidePanel",
"storage",
"scripting"
],
"host_permissions": [
"<all_urls>"
]
}
打開側邊欄:
// background.ts
chrome.action.onClicked.addListener(async (tab) => {
await chrome.sidePanel.open({ windowId: tab.windowId });
});
關鍵區別:
劫持實現原理參考我上篇文章:【前端效率工具】再也不用 APIfox 聯調!零侵入 Mock,全程不改代碼、不开代理
核心代碼:
injected.ts
const originalFetch = window.fetch;
window.fetch = async function(input, init) {
const url = typeof input === 'string' ? input : input.url;
const method = init?.method || 'GET';
// 查找匹配的規則
const rule = await findMatchedRule(url, method);
if (rule) {
// 延時處理
if (rule.delay > 0) {
await new Promise(resolve => setTimeout(resolve, rule.delay));
}
// 返回指定狀態碼
return new Response(
JSON.stringify(rule.data),
{
status: rule.statusCode || 200,
statusText: getStatusText(rule.statusCode),
headers: { 'Content-Type': 'application/json' }
}
);
}
// 不攔截,調用原始 fetch
return originalFetch.apply(this, arguments as any);
};
// 狀態碼文本映射
function getStatusText(code: number): string {
const statusTexts: Record<number, string> = {
200: 'OK',
400: 'Bad Request',
401: 'Unauthorized',
403: 'Forbidden',
404: 'Not Found',
500: 'Internal Server Error',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout'
};
return statusTexts[code] || 'Unknown';
}
匹配規則:
async function findMatchedRule(url: string, method: string) {
// 從 storage 獲取規則
const { rules } = await chrome.storage.local.get('rules');
return rules.find((rule: Rule) => {
if (!rule.enabled) return false;
// 方法匹配
if (rule.method !== 'ALL' && rule.method !== method) {
return false;
}
// URL 匹配
if (rule.matchMode === 'contains') {
return url.includes(rule.url);
} else if (rule.matchMode === 'exact') {
return url === rule.url;
} else if (rule.matchMode === 'regex') {
return new RegExp(rule.url).test(url);
}
return false;
});
}
支持的匹配模式:
/api/user 可以匹配 /api/user/list、/api/user/detail/api/user/\d+ 可以匹配 /api/user/123Prompt 設計:
const buildPrompt = (userInput: string) => {
return `
你是一個專業的 Mock 數據生成助手。
用戶需求:${userInput}
請生成符合以下規範的 JSON 數據:
1. 必須是有效的 JSON 格式
2. 包含常見的響應結構(code, msg, data)
3. 數據要真實合理(中文姓名、真實郵箱格式等)
4. 如果是列表,生成 2-3 條示例數據
只返回 JSON,不要有其他說明文字。
`.trim();
};
生成邏輯:
const generateMockData = async () => {
if (!aiPrompt.value) {
ElMessage.warning('請輸入數據描述');
return;
}
generating.value = true;
try {
const response = await fetch('YOUR_AI_API_ENDPOINT', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt: buildPrompt(aiPrompt.value),
model: 'gpt-3.5-turbo'
})
});
const data = await response.json();
// 解析 AI 返回的 JSON
const mockData = JSON.parse(data.choices[0].message.content);
// 填充到編輯器
form.data = JSON.stringify(mockData, null, 2);
ElMessage.success('✨ AI 生成成功');
} catch (error) {
ElMessage.error('生成失敗:' + error.message);
} finally {
generating.value = false;
}
};
interface Rule {
id: string;
remark: string; // 規則名稱
url: string; // URL 匹配
matchMode: 'contains' | 'exact' | 'regex';
method: 'ALL' | 'GET' | 'POST' | 'PUT' | 'DELETE';
statusCode: number; // 🆕 狀態碼(默認 200)
delay: number; // 🆕 延時(毫秒,默認 0)
data: Record<string, any>; // Mock 數據
enabled: boolean; // 是否啟用
createdAt: number; // 創建時間
}
存儲和讀取:
// 保存規則
const saveRules = async () => {
await chrome.storage.local.set({ rules: rules.value });
};
// 加載規則
const loadRules = async () => {
const result = await chrome.storage.local.get('rules');
rules.value = result.rules || [];
};
// 監聽變化
chrome.storage.onChanged.addListener((changes, areaName) => {
if (areaName === 'local' && changes.rules) {
rules.value = changes.rules.newValue;
}
});
這次重構主要做了四件事:
這四個功能組合起來,基本覆蓋了前端開發中 90% 的 Mock 需求。
如果你也在等後端介面,或者被 Popup 小窗口折磨過,真的可以試試這個插件,保證你用了就回不去了。
如果覺得對您有幫助,歡迎點贊 👍 收藏 ⭐ 關注 🔔 支持一下!
往期實戰推薦: