mirror of
https://github.com/daief/gm-response-proxy.git
synced 2025-11-30 00:12:47 +08:00
wip: refine code
This commit is contained in:
@@ -21,8 +21,9 @@
|
||||
<div v-for="(rule, idx2) in it.rules" :key="idx2">
|
||||
<div>
|
||||
<label>rule-{{ idx2 }}:</label>
|
||||
<div>apiTest: <input v-model="rule.apiTest" /></div>
|
||||
<div>apiTest2: <input v-model="rule.apiTest" /></div>
|
||||
<div>
|
||||
apiTest: <input v-model="rule.apiTest" style="width: 300px" />
|
||||
</div>
|
||||
<div>response: <textarea v-model="rule.response" /></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +50,6 @@ export default defineComponent({
|
||||
|
||||
onMounted(() => {
|
||||
state.matchedSetList = Store.getMatchedSetList();
|
||||
console.log(state.matchedSetList);
|
||||
});
|
||||
|
||||
watch(
|
||||
@@ -73,14 +73,11 @@ export default defineComponent({
|
||||
show.value = false;
|
||||
},
|
||||
handleAdd: () => {
|
||||
state.matchedSetList = [
|
||||
{
|
||||
domainTest: location.hostname,
|
||||
rules: [],
|
||||
id: uuid4(),
|
||||
},
|
||||
...state.matchedSetList,
|
||||
];
|
||||
state.matchedSetList.unshift({
|
||||
domainTest: location.hostname,
|
||||
rules: [],
|
||||
id: uuid4(),
|
||||
});
|
||||
},
|
||||
handleAddRule: (i: number) => {
|
||||
state.matchedSetList[i].rules.push({
|
||||
|
||||
@@ -5,6 +5,7 @@ export const cache = new WeakMap<
|
||||
{
|
||||
method: string;
|
||||
url: string;
|
||||
[k: string]: any;
|
||||
}
|
||||
>();
|
||||
|
||||
|
||||
@@ -1,63 +1,82 @@
|
||||
import { cache, safeParse, vmCtx } from '@/common';
|
||||
import { cache, vmCtx } from '@/common';
|
||||
import { Store } from '@/data';
|
||||
|
||||
const originalFetch = vmCtx.fetch;
|
||||
const originalJson = Response.prototype.json;
|
||||
const originalText = Response.prototype.text;
|
||||
|
||||
function proxyRes(response: Response) {
|
||||
const ruleSet = Store.findCurrentSet();
|
||||
const matchedRule = ruleSet.rules.find(it =>
|
||||
response.url.includes(it.apiTest)
|
||||
);
|
||||
|
||||
const res = matchedRule?.response;
|
||||
const payload = cache.get(response);
|
||||
return matchedRule?.response;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
GM_log(
|
||||
`❗️ [fetch] Response is proxyed:\n`,
|
||||
`${payload?.method || ''} ${response.url}\n`,
|
||||
safeParse(res)
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
function log({ method, url, status, response }: any) {
|
||||
GM_log(`❗️ [fetch] Response is proxyed:\n`);
|
||||
console.table({
|
||||
method,
|
||||
url,
|
||||
status,
|
||||
'proxyed response': response,
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof Response !== 'undefined') {
|
||||
const nativeFetch = vmCtx.fetch;
|
||||
const nativeJson = Response.prototype.json;
|
||||
const nativeText = Response.prototype.text;
|
||||
|
||||
Response.prototype.json = async function (this: Response, ...args) {
|
||||
const nativeRes = await originalJson.apply(this, args);
|
||||
const res = proxyRes(this);
|
||||
if (res) {
|
||||
try {
|
||||
return JSON.parse(res);
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`❌ Error when parse proxy response for [${this.url}]. Use original result.`
|
||||
);
|
||||
return nativeRes;
|
||||
}
|
||||
const nativeRes = await nativeJson.apply(this, args);
|
||||
const payload = cache.get(this);
|
||||
|
||||
if (payload?.proxyedResponse) {
|
||||
log({
|
||||
method: payload.method,
|
||||
url: this.url,
|
||||
status: this.status,
|
||||
response: payload.proxyedResponse,
|
||||
});
|
||||
return JSON.parse(payload.proxyedResponse);
|
||||
}
|
||||
|
||||
return nativeRes;
|
||||
};
|
||||
|
||||
Response.prototype.text = async function (this: Response, ...args) {
|
||||
const nativeRes = await originalText.apply(this, args);
|
||||
const res = proxyRes(this);
|
||||
if (res) {
|
||||
return res;
|
||||
const nativeRes = await nativeText.apply(this, args);
|
||||
const payload = cache.get(this);
|
||||
|
||||
if (payload?.proxyedResponse) {
|
||||
log({
|
||||
method: payload.method,
|
||||
url: this.url,
|
||||
status: this.status,
|
||||
response: payload.proxyedResponse,
|
||||
});
|
||||
return payload.proxyedResponse;
|
||||
}
|
||||
|
||||
return nativeRes;
|
||||
};
|
||||
|
||||
vmCtx.fetch = async function (...args) {
|
||||
const res: Response = await originalFetch.apply(this, args);
|
||||
vmCtx.fetch = async function (input: RequestInfo, init?: RequestInit) {
|
||||
let method = 'GET';
|
||||
if (input instanceof Request) {
|
||||
method = input.method;
|
||||
} else {
|
||||
method = init?.method || method;
|
||||
}
|
||||
|
||||
const res: Response = await nativeFetch.apply(this, [input, init]);
|
||||
|
||||
const proxyedResponse = proxyRes(res);
|
||||
|
||||
cache.set(res, {
|
||||
method: args[1]?.method || 'GET',
|
||||
method,
|
||||
url: res.url,
|
||||
proxyedResponse,
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,58 +1,56 @@
|
||||
import { cache, safeParse } from '@/common';
|
||||
import { vmCtx } from '@/common';
|
||||
import { Store } from '@/data';
|
||||
|
||||
const originalOpen = XMLHttpRequest.prototype.open;
|
||||
const originalSend = XMLHttpRequest.prototype.send;
|
||||
const NativeXMLHttpRequest = vmCtx.XMLHttpRequest;
|
||||
|
||||
XMLHttpRequest.prototype.open = function (...args: any[]) {
|
||||
cache.set(this, {
|
||||
method: args[0],
|
||||
url: args[1],
|
||||
});
|
||||
return originalOpen.apply(this, args);
|
||||
};
|
||||
|
||||
XMLHttpRequest.prototype.send = function (
|
||||
this: XMLHttpRequest,
|
||||
...args: any[]
|
||||
vmCtx.XMLHttpRequest = class extends (
|
||||
NativeXMLHttpRequest
|
||||
) {
|
||||
this.addEventListener(
|
||||
'readystatechange',
|
||||
function () {
|
||||
const payload = cache.get(this);
|
||||
#mockResponse: string;
|
||||
#url: string;
|
||||
#method: string;
|
||||
#proxyed: boolean = false;
|
||||
|
||||
if (!payload) {
|
||||
return;
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const ruleSet = Store.findCurrentSet();
|
||||
const matchedRule = ruleSet.rules.find(it =>
|
||||
payload.url.includes(it.apiTest)
|
||||
);
|
||||
['load', 'error'].forEach(ev => {
|
||||
this.addEventListener(ev, () => {
|
||||
if (!this.#proxyed) return;
|
||||
|
||||
if (matchedRule?.response && this.readyState === 3) {
|
||||
Object.defineProperty(this, 'response', {
|
||||
writable: true,
|
||||
});
|
||||
Object.defineProperty(this, 'responseText', {
|
||||
writable: true,
|
||||
GM_log(`❗️ [XHR] Response is proxyed:\n`);
|
||||
console.table({
|
||||
method: this.#method,
|
||||
url: this.#url,
|
||||
status: this.status,
|
||||
'proxyed response': this.#mockResponse,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
this.response = matchedRule.response;
|
||||
// @ts-ignore
|
||||
this.responseText = matchedRule.response;
|
||||
get response() {
|
||||
return this.#mockResponse || super.response;
|
||||
}
|
||||
|
||||
GM_log(
|
||||
`❗️ [XHR] Response is proxyed:\n`,
|
||||
`${payload.method} ${payload.url}\n`,
|
||||
safeParse(matchedRule.response)
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
capture: true,
|
||||
get responseText() {
|
||||
return this.#mockResponse || super.responseText;
|
||||
}
|
||||
|
||||
open(method: string, url: string): void {
|
||||
this.#method = method;
|
||||
this.#url = url;
|
||||
|
||||
const ruleSet = Store.findCurrentSet();
|
||||
const matchedRule = ruleSet.rules.find(it =>
|
||||
this.#url.includes(it.apiTest)
|
||||
);
|
||||
|
||||
if (matchedRule?.response) {
|
||||
this.#mockResponse = matchedRule.response;
|
||||
this.#proxyed = true;
|
||||
}
|
||||
);
|
||||
return originalSend.apply(this, args);
|
||||
|
||||
return super.open(method, url);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user