使用说明
- 修改第7行的
match
- 第15~34行,是我自己的业务逻辑,需要改成你自己的
- 第42行的
API_CONFIG定义了每个接口的匹配方式和回调函数,也需要改成你自己的业务逻辑
- 修改完成后,复制到油猴脚本中即可
代码
(function () {
'use strict';
const currentAccount = "acc1";
const accountConf = {
"acc1": {
"总人数": 400,
"deptMemberCount": {
"部门1": 150,
"部门2": 80,
},
},
"acc2": {
"总人数": 3574,
"deptMemberCount": {
"部门1": 3380,
"部门2": 1256,
},
}
}
const config = accountConf[currentAccount] || accountConf["acc1"];
const requestMap = new Map();
const API_CONFIG = {
'get_sub_depts_page': function (response, requestInfo) {
if (!response.result) return response;
const list = response.result.list;
for (let i = 0; i < list.length; i++) {
if (list[i]['name'] in config['deptMemberCount']) {
list[i].memberCount = config['deptMemberCount'][list[i]['name']];
continue;
}
}
return response;
},
'statistic_realtime': function (response, requestInfo) {
if (!response.result) return response;
response.result.activeCount = config['总人数'] - 1;
response.result.memCount = config['总人数'];
return response;
},
};
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url) {
requestMap.set(this, {
method: method,
url: url,
body: null
});
let matchedCallback = null;
for (const [path, callback] of Object.entries(API_CONFIG)) {
if (url.includes(path)) {
console.log(`拦截到接口: ${url}`);
matchedCallback = callback;
break;
}
}
if (matchedCallback) {
const originalOnReadyStateChange = this.onreadystatechange;
const xhr = this;
this.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
const requestInfo = requestMap.get(xhr) || {};
const modifiedResponse = matchedCallback(response, requestInfo);
Object.defineProperty(xhr, 'responseText', {
writable: true,
value: JSON.stringify(modifiedResponse)
});
Object.defineProperty(xhr, 'response', {
writable: true,
value: modifiedResponse
});
console.log(`xhr - ${url} - 已修改`);
} catch (e) {
console.error('修改响应失败:', e);
}
}
if (originalOnReadyStateChange) {
originalOnReadyStateChange.apply(this, arguments);
}
};
}
originalOpen.apply(this, arguments);
};
const originalSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function (body) {
const requestInfo = requestMap.get(this);
if (requestInfo) {
requestInfo.body = body;
}
return originalSend.apply(this, arguments);
};
const originalFetch = window.fetch;
window.unsafeWindow.fetch = function (input, init) {
const url = typeof input === 'string' ? input : input.url;
const method = (init && init.method) || 'GET';
const body = (init && init.body) || null;
let matchedCallback = null;
for (const [path, callback] of Object.entries(API_CONFIG)) {
if (url.includes(path)) {
console.log(`拦截到fetch请求: ${url}`);
matchedCallback = callback;
break;
}
}
if (!matchedCallback) {
return originalFetch(input, init);
}
const requestInfo = {
method: method,
url: url,
body: body
};
return originalFetch(input, init).then(response => {
return response.text().then(text => {
try {
const data = JSON.parse(text);
const modifiedData = matchedCallback(data, requestInfo);
const modifiedText = JSON.stringify(modifiedData);
console.log(`fetch - ${url} - 已修改`);
return new Response(modifiedText, {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
} catch (e) {
console.error('修改fetch响应失败:', e);
return new Response(text, {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
}
});
});
};
console.log('接口修改脚本已加载,当前配置的接口数量:', Object.keys(API_CONFIG).length);
})();
其他说明
- 文章参考了油猴脚本重写fetch和xhr请求,再加上大模型改成批处理的方式,感谢大佬的分享。
- 除了使用油猴外,脚本猫也是一个不错的选择。
- 本地调试期间,为了方便写代码,可以利用@require调用本地脚本的方法。