wip: proxy fetch

This commit is contained in:
daief
2020-11-30 12:29:51 +08:00
parent c76a1e585b
commit 39777aa84f
6 changed files with 73 additions and 7 deletions

View File

@@ -11,3 +11,5 @@ declare function GM_log(...msg: any[]): void;
declare function GM_setValue(name: string, value: any): void;
declare function GM_addStyle(css: string): void;
declare function GM_getValue(name: string, defaultValue?: any): any;
declare const unsafeWindow: Window & typeof globalThis;

View File

@@ -1,7 +1,7 @@
export * from './utils';
export const cache = new WeakMap<
XMLHttpRequest,
XMLHttpRequest | Response,
{
method: string;
url: string;
@@ -9,3 +9,6 @@ export const cache = new WeakMap<
>();
export const NAMESPACE = location.host;
export const vmCtx: Window & typeof globalThis =
typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;

View File

@@ -9,6 +9,7 @@
background-color: #6cf;
opacity: 0.5;
transition: opacity 0.3s;
box-shadow: 0 0 10px 0px rgb(0 0 0 / 35%);
&:hover {
opacity: 1;

View File

@@ -1,5 +1,7 @@
import './proxy/fetch';
import './proxy/xhr';
import './global.less';
import { vmCtx } from './common';
// TODO change to async
import { render } from './SettingPanel';
@@ -12,7 +14,7 @@ let tX = 0;
let tY = 0;
let elRect: DOMRect | null = null;
window.addEventListener('DOMContentLoaded', () => {
vmCtx.addEventListener('DOMContentLoaded', () => {
const el = document.createElement('div');
el.innerText = '设置';
el.className = 'response-proxy-page-root-fixed-button';
@@ -39,7 +41,7 @@ window.addEventListener('DOMContentLoaded', () => {
tY = e.clientY - elRect.top;
});
window.addEventListener('mouseup', async e => {
vmCtx.addEventListener('mouseup', async e => {
isDrag = false;
if (isMove) {
isMove = false;
@@ -51,7 +53,7 @@ window.addEventListener('DOMContentLoaded', () => {
}
});
window.addEventListener('mousemove', e => {
vmCtx.addEventListener('mousemove', e => {
isMove = true;
if (!isDrag) {
return;
@@ -60,11 +62,11 @@ window.addEventListener('DOMContentLoaded', () => {
e.preventDefault();
let left = e.clientX - tX;
left = Math.min(left, window.innerWidth - elRect!.width);
left = Math.min(left, vmCtx.innerWidth - elRect!.width);
left = Math.max(left, 0);
let top = e.clientY - tY;
top = Math.min(top, window.innerHeight - elRect!.height);
top = Math.min(top, vmCtx.innerHeight - elRect!.height);
top = Math.max(top, 0);
el.style.left = left + 'px';

58
src/proxy/fetch.ts Normal file
View File

@@ -0,0 +1,58 @@
import { cache, safeParse, 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);
if (res) {
GM_log(
`❗️ Response is proxyed:\n`,
`${payload?.method || ''} ${response.url}\n`,
safeParse(res)
);
}
return res;
}
if (typeof Response !== 'undefined') {
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) {
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;
}
return nativeRes;
};
vmCtx.fetch = async function (...args) {
const res: Response = await originalFetch.apply(this, args);
cache.set(res, {
method: args[1]?.method || 'GET',
url: res.url,
});
return res;
};
}

View File

@@ -30,7 +30,7 @@ XMLHttpRequest.prototype.send = function (
payload.url.includes(it.apiTest)
);
if (matchedRule && matchedRule.response && this.readyState === 3) {
if (matchedRule?.response && this.readyState === 3) {
Object.defineProperty(this, 'response', {
writable: true,
});