(function() {
// -------------------- 加载 XLSX 库 --------------------
const xlsxScript = document.createElement("script");
xlsxScript.src = "https://cdn.bootcdn.net/ajax/libs/xlsx/0.18.5/xlsx.full.min.js";
xlsxScript.onload = () => console.log("✅ XLSX 已加载");
document.head.appendChild(xlsxScript);
// -------------------- 创建按钮 --------------------
const container = document.createElement("div");
container.style.position = "fixed";
container.style.top = "10px";
container.style.right = "10px";
container.style.zIndex = 999999;
container.style.display = "flex";
container.style.flexDirection = "column";
container.style.gap = "8px";
let collecting = false;
const requests = [];
function makeBtn(text, onclick) {
const btn = document.createElement("button");
btn.textContent = text;
btn.style.padding = "6px 10px";
btn.style.background = "#4CAF50";
btn.style.color = "white";
btn.style.border = "none";
btn.style.borderRadius = "4px";
btn.style.cursor = "pointer";
btn.style.fontSize = "14px";
btn.onclick = onclick;
return btn;
}
container.appendChild(makeBtn("开始收集接口", () => {
collecting = true;
alert("✅ 开始收集接口,请点击页面操作产生请求");
}));
container.appendChild(makeBtn("导出接口列表", exportExcel));
container.appendChild(makeBtn("清空记录", () => {
requests.length = 0;
alert("✅ 已清空记录");
}));
document.body.appendChild(container);
// -------------------- 工具函数 --------------------
function normalize(url) {
try {
const u = new URL(url, location.origin);
const path = u.pathname;
const idx = path.indexOf("api/");
return idx >= 0 ? path.slice(idx + 4) : path;
} catch {
const path = url.split("?")[0];
const idx = path.indexOf("api/");
return idx >= 0 ? path.slice(idx + 4) : path;
}
}
function isApiRequest(url) {
// 过滤掉静态资源
return !url.match(/\.(js|json|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|map)(\?|$)/i);
}
function exportExcel() {
if (!window.XLSX) {
alert("❌ XLSX 库未加载,请稍等");
return;
}
const filtered = requests.filter(r => isApiRequest(r.url));
if (filtered.length === 0) {
alert("⚠️ 没有接口记录,请先点击页面操作产生接口");
return;
}
const unique = new Set();
filtered.forEach(({ url, method }) => {
const key = normalize(url) + " | " + method.toUpperCase();
unique.add(key);
});
// 排序:先按 method,再按 url
const methodOrder = { GET: 1, POST: 2, PUT: 3, DELETE: 4 };
const sorted = Array.from(unique).sort((a, b) => {
const [urlA, methodA] = a.split(" | ");
const [urlB, methodB] = b.split(" | ");
const orderA = methodOrder[methodA] || 99;
const orderB = methodOrder[methodB] || 99;
if (orderA === orderB) return urlA.localeCompare(urlB);
return orderA - orderB;
});
const rows = [["接口地址", "请求方式"]];
sorted.forEach(entry => {
const [url, method] = entry.split(" | ");
rows.push([url, method]);
});
const worksheet = XLSX.utils.aoa_to_sheet(rows);
// 设置列宽
worksheet["!cols"] = [{ wch: 60 }, { wch: 10 }];
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "接口列表");
// 文件名带时间戳
const timestamp = new Date().toISOString().replace(/[:T]/g, "-").split(".")[0];
XLSX.writeFile(workbook, `接口列表_${timestamp}.xlsx`);
alert("✅ 已导出接口列表");
}
// -------------------- 劫持 fetch --------------------
const originalFetch = window.fetch;
window.fetch = async (...args) => {
if (collecting) {
try {
const [url, options] = args;
const method = (options && options.method) || "GET";
if (isApiRequest(url)) requests.push({ url, method });
} catch (e) {}
}
return originalFetch.apply(this, args);
};
// -------------------- 劫持 XHR --------------------
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
if (collecting) {
try {
if (isApiRequest(url)) requests.push({ url, method });
} catch (e) {}
}
return originalOpen.call(this, method, url, ...rest);
};
// -------------------- 劫持 axios --------------------
if (window.axios) {
const originalRequest = window.axios.request;
window.axios.request = function(config) {
if (collecting) {
try {
if (isApiRequest(config.url))
requests.push({ url: config.url, method: (config.method || "GET").toUpperCase() });
} catch (e) {}
}
return originalRequest.call(this, config);
};
}
console.log("✅ 接口收集工具已注入页面上下文,XLSX 库正在加载");
})();