Skip to content

Commit

Permalink
🐛 修复后台脚本无法处理blob的问题 #34
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Feb 1, 2022
1 parent a706827 commit 7b81677
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 41 deletions.
25 changes: 24 additions & 1 deletion src/apps/grant/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,6 @@ export class BackgroundGrant {
@BackgroundGrant.GMFunction({
confirm: (grant: Grant, script: Script) => {
return new Promise(resolve => {
console.log(grant, script);
const config = <GM_Types.XHRDetails>grant.params[0];
const url = new URL(config.url);
if (script.metadata['connect']) {
Expand Down Expand Up @@ -664,6 +663,30 @@ export class BackgroundGrant {
});
}

// CAT_fetchBlob与CAT_createBlobUrl 沙盒中才有效,前端的在src/content.ts中处理
@BackgroundGrant.GMFunction({
default: true
})
protected CAT_fetchBlob(grant: Grant): Promise<any> {
return new Promise(resolve => {
const handler = async () => {
const resp=await (await fetch(<string>grant.params[0])).blob();
console.log('fetch',resp);
resolve(resp);
}
void handler();
});
}

@BackgroundGrant.GMFunction({
default: true
})
protected CAT_createBlobUrl(grant: Grant): Promise<any> {
return new Promise(resolve => {
resolve(URL.createObjectURL(<Blob>grant.params[0]));
});
}

@BackgroundGrant.GMFunction({
confirm: (grant: Grant, script: Script) => {
return new Promise((resolve, reject) => {
Expand Down
3 changes: 1 addition & 2 deletions src/apps/grant/frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export class FrontendGrant implements ScriptContext {
});
}

@FrontendGrant.GMFunction({ depend: ['CAT_fetchBlob', 'CAT_createBlobUrl','CAT_abortXhr'] })
@FrontendGrant.GMFunction({ depend: ['CAT_fetchBlob', 'CAT_createBlobUrl', 'CAT_abortXhr'] })
public GM_xmlhttpRequest(details: GM_Types.XHRDetails): GM_Types.AbortHandle<void> {
let abort = () => { return };
const handler = async () => {
Expand Down Expand Up @@ -262,7 +262,6 @@ export class FrontendGrant implements ScriptContext {
details.onabort && details.onabort();
break;
case 'requestId':
console.log(data.data);
abort = () => {
this.CAT_abortXhr(<number>data.data);
}
Expand Down
1 change: 1 addition & 0 deletions src/apps/msg-center/msg-center.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { compileScript } from "@App/pkg/sandbox/compile";

export type ListenCallback = (msg: any, port: chrome.runtime.Port) => Promise<any> | any;

Expand Down
1 change: 0 additions & 1 deletion src/apps/script/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,6 @@ export class ScriptManager extends Manager {
}
}
await this.scriptModel.save(script);
console.log(script.metadata['connect']);
AppEvent.trigger(ScriptStatusChange, script);
return resolve(true);
});
Expand Down
2 changes: 1 addition & 1 deletion src/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ chrome.runtime.sendMessage('runScript', (event: unknown) => {
browserMsg.send(msg.flag, msg);
break;
case 'CAT_createBlobUrl':
msg.data = URL.createObjectURL(msg.params[0]);
msg.data = URL.createObjectURL(<Blob>msg.params[0]);
browserMsg.send(msg.flag, msg);
break;
default:
Expand Down
4 changes: 2 additions & 2 deletions src/pkg/sandbox/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export function compileScriptCode(script: ScriptCache): string {
}

// 编译成脚本方法
export function compileScript(script: ScriptCache): any {
return new Function('context', script.code);
export function compileScript(script: ScriptCache): (param: AnyMap) => void {
return <(param: AnyMap) => void>new Function('context', script.code);
}

// 设置api依赖
Expand Down
84 changes: 50 additions & 34 deletions src/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CronJob } from 'cron';
import { buildThis } from '@App/pkg/sandbox/sandbox';
import { buildThis } from './pkg/sandbox/sandbox';
import { SandboxContext } from './apps/grant/frontend';
import { SendLogger } from './pkg/utils/utils';
import { App, ENV_FRONTEND, InitApp } from './apps/app';
Expand All @@ -23,46 +23,50 @@ type ExecType = 'run' | 'crontab' | 'retry' | 'debug';

async function execScript(
script: Script,
func: Function,
func: (param: AnyMap) => any,
context: SandboxContext,
type: ExecType = 'run',
): Promise<boolean> {
return new Promise(async (resolve, reject) => {
return new Promise((resolve, reject) => {
//使用SandboxContext接管postRequest
script.delayruntime = 0;
context.CAT_setRunError('', 0);
script.lastruntime = new Date().getTime();
context.CAT_setLastRuntime(script.lastruntime);
SendLogger(LOGGER_LEVEL_INFO, type, 'exec script id: ' + script.id, script.name, script.id);
SendLogger(LOGGER_LEVEL_INFO, type, 'exec script id: ' + script.id.toString(), script.name, script.id);
let execRet;
try {
execRet = func(buildThis(window, context));
} catch (error: any) {
let msg = 'exec script id: ' + script.id + ' time: ' + (new Date().getTime() - (script.lastruntime || 0)).toString() + 'ms'
if (error) {
let msg = 'exec script id: ' + script.id.toString() + ' time: ' + (new Date().getTime() - (script.lastruntime || 0)).toString() + 'ms'
let errMsg = '';
if (typeof error === 'string') {
msg += ' error: ' + error;
errMsg = error;
} else {
errMsg = 'unknow error';
}
SendLogger(LOGGER_LEVEL_ERROR, type, msg, script.name, script.id);
script.delayruntime = 0;
context.CAT_setRunError(error, script.delayruntime);
context.CAT_setRunError(errMsg, script.delayruntime);
reject(error);
return
}
if (execRet instanceof Promise) {
execRet
.then((result: any) => {
let msg = 'exec script id: ' + script.id + ' time: ' + (new Date().getTime() - (script.lastruntime || 0)).toString() + 'ms'
if (result) {
let msg = 'exec script id: ' + script.id.toString() + ' time: ' + (new Date().getTime() - (script.lastruntime || 0)).toString() + 'ms'
if (typeof result == 'string') {
msg += ' result: ' + result;
}
SendLogger(LOGGER_LEVEL_INFO, type, msg, script.name, script.id);
context.CAT_runComplete();
resolve(result);
resolve(true);
})
.catch((error: string, delayrun = 0) => {
let msg = 'exec script id: ' + script.id + ' time: ' + (new Date().getTime() - (script.lastruntime || 0)).toString() + 'ms'
let msg = 'exec script id: ' + script.id.toString() + ' time: ' + (new Date().getTime() - (script.lastruntime || 0)).toString() + 'ms'
if (error) {
msg += ' error: ' + error + (delayrun ? ' delayrun: ' + delayrun : '')
msg += ' error: ' + error + (delayrun ? ' delayrun: ' + delayrun.toString() : '')
}
SendLogger(LOGGER_LEVEL_ERROR, type, msg, script.name, script.id);
if (delayrun > 0) {
Expand All @@ -74,14 +78,26 @@ async function execScript(
reject(error);
});
} else {
let result = ' result:';
switch (typeof execRet) {
case 'string':
result += execRet;
break;
case 'undefined':
result = '';
break;
default:
result += JSON.stringify(execRet);
break;
}
SendLogger(
LOGGER_LEVEL_INFO,
type,
'exec script id: ' +
script.id +
script.id.toString() +
' time: ' +
(new Date().getTime() - (script.lastruntime || 0)).toString() +
'ms' + (execRet ? ' result:' + execRet : ''),
'ms' + result,
script.name, script.id
);
context.CAT_runComplete();
Expand All @@ -95,16 +111,16 @@ function start(script: ScriptCache): any {
return runCrontab(script);
} else if (script.metadata['background']) {
const context = createSandboxContext(script);
App.Cache.set('script:' + script.id, context);
execScript(script, compileScript(script), context, 'run');
return top!.postMessage({ action: 'start', data: '' }, '*');
void App.Cache.set('script:' + script.id.toString(), context);
void execScript(script, compileScript(script), context, 'run');
return top?.postMessage({ action: 'start', data: '' }, '*');
}
}

function runCrontab(script: ScriptCache) {
const crontab = script.metadata['crontab'];
const context = createSandboxContext(script);
App.Cache.set('script:' + script.id, context);
void App.Cache.set('script:' + script.id.toString(), context);
const func = compileScript(script);

const list = new Array<CronJob>();
Expand Down Expand Up @@ -132,13 +148,13 @@ function runCrontab(script: ScriptCache) {
() => {
if (oncePos) {
if (!script.lastruntime) {
execScript(script, func, context, 'crontab');
void execScript(script, func, context, 'crontab');
return;
}
const now = new Date();
if (script.delayruntime && script.delayruntime < now.getTime()) {
//TODO:使用单独的计时器执行
execScript(script, func, context, 'retry');
void execScript(script, func, context, 'retry');
return;
}
if (script.lastruntime > now.getTime()) {
Expand Down Expand Up @@ -167,10 +183,10 @@ function runCrontab(script: ScriptCache) {
default:
}
if (flag) {
execScript(script, func, context, 'crontab');
void execScript(script, func, context, 'crontab');
}
} else {
execScript(script, func, context, 'crontab');
void execScript(script, func, context, 'crontab');
}
},
null,
Expand All @@ -179,44 +195,44 @@ function runCrontab(script: ScriptCache) {
list.push(cron);
});
cronjobMap.set(script.id, list);
return top!.postMessage({ action: 'start', data: '' }, '*');
return top?.postMessage({ action: 'start', data: '' }, '*');
}

async function exec(script: ScriptCache, isdebug: boolean) {
function exec(script: ScriptCache, isdebug: boolean) {
const context = createSandboxContext(script);
App.Cache.set('script:' + (isdebug ? 'debug:' : '') + script.id, context);
void App.Cache.set('script:' + (isdebug ? 'debug:' : '') + script.id.toString(), context);
execScript(script, compileScript(script), context, isdebug ? 'debug' : 'run').then(result => {
top!.postMessage({ action: 'exec respond', data: 'success', result: result }, '*');
top?.postMessage({ action: 'exec respond', data: 'success', result: result }, '*');
}).catch(error => {
top!.postMessage({ action: 'exec respond', data: 'error', error: error }, '*');
top?.postMessage({ action: 'exec respond', data: 'error', error: error }, '*');
});
return top!.postMessage({ action: 'exec', data: '' }, '*');
return top?.postMessage({ action: 'exec', data: '' }, '*');
}

async function disable(script: Script) {
const context = <SandboxContext>(
await App.Cache.get('script:' + script.id)
await App.Cache.get('script:' + script.id.toString())
);
if (context) {
context.destruct();
}
if (script.type != SCRIPT_TYPE_CRONTAB) {
return top!.postMessage({ action: 'disable' }, '*');
return top?.postMessage({ action: 'disable' }, '*');
}
const list = cronjobMap.get(script.id);
if (!list) {
return top!.postMessage({ action: 'disable' }, '*');
return top?.postMessage({ action: 'disable' }, '*');
}
list.forEach((val) => {
val.stop();
});
cronjobMap.delete(script.id);
return top!.postMessage({ action: 'disable' }, '*');
return top?.postMessage({ action: 'disable' }, '*');
}

async function stop(script: Script, isdebug: boolean) {
const context = <SandboxContext>(
await App.Cache.get('script:' + (isdebug ? 'debug:' : '') + script.id)
await App.Cache.get('script:' + (isdebug ? 'debug:' : '') + script.id.toString())
);
if (context) {
if (script.type == SCRIPT_TYPE_CRONTAB) {
Expand All @@ -225,7 +241,7 @@ async function stop(script: Script, isdebug: boolean) {
context.destruct();
}
}
return top!.postMessage({ action: 'stop' }, '*');
return top?.postMessage({ action: 'stop' }, '*');
}

function getWeek(date: Date) {
Expand Down

0 comments on commit 7b81677

Please sign in to comment.