fix: proxy requests from sandbox
diff --git a/src/editor/sandbox/index.js b/src/editor/sandbox/index.js
index 56ee418..5e2c742 100644
--- a/src/editor/sandbox/index.js
+++ b/src/editor/sandbox/index.js
@@ -4,6 +4,9 @@
import loopController from 'raw-loader!./loopController';
import showDebugDirtyRect from 'raw-loader!../../dep/showDebugDirtyRect';
import estraverse from 'raw-loader!./estraverse.browser';
+import workerJS from 'raw-loader!!./worker';
+
+let sandboxWorker;
export function createSandbox(
container,
@@ -118,6 +121,14 @@
case 'cssParsed':
onCSSParsed(data.css);
break;
+ case 'requestProxy':
+ const [method, url, async] = data.args;
+ sandboxWorker.postMessage({
+ reqId: data.reqId,
+ args: [method, new URL(url, location.origin).toString(), async],
+ body: data.body
+ });
+ break;
default:
break;
}
@@ -129,6 +140,11 @@
window.addEventListener('message', hanldeMessage, false);
+ if (!sandboxWorker) {
+ sandboxWorker = new Worker(URL.createObjectURL(new Blob([workerJS])));
+ }
+ sandboxWorker.onmessage = (e) => sendMessage('requestProxyRes', e.data);
+
return {
dispose() {
sendMessage('dispose');
diff --git a/src/editor/sandbox/setup.js b/src/editor/sandbox/setup.js
index 63480b2..8e15594 100644
--- a/src/editor/sandbox/setup.js
+++ b/src/editor/sandbox/setup.js
@@ -288,9 +288,60 @@
// const { action, ...args } = ev.data;
const action = ev.data.action;
delete ev.data.action;
+ if (action === 'requestProxyRes') {
+ return onXHRRes(ev.data);
+ }
typeof api[action] === 'function' && api[action].apply(api, [ev.data]);
}
+ const pendingXHRMap = new Map();
+
+ function onXHRRes(e) {
+ const xhr = pendingXHRMap.get(e.reqId);
+ if (xhr) {
+ const args = xhr.__args.slice();
+ if (e.type === 'load') {
+ const blob = new Blob([e.res], {
+ // FIXME how to determine the response content type
+ // to enable jQuery can detect the right type?
+ // type: 'application/json'
+ });
+ const blobURL = URL.createObjectURL(blob);
+ args[1] = blobURL;
+ xhr.addEventListener('load', () => URL.revokeObjectURL(blobURL));
+ } else {
+ args[1] = null;
+ }
+ console.log(args[1]);
+ nativeXHROpen.apply(xhr, args);
+ nativeXHRSend.apply(xhr);
+
+ pendingXHRMap.delete(e.reqId);
+ }
+ }
+
+ const nativeXHROpen = XMLHttpRequest.prototype.open;
+ const nativeXHRSend = XMLHttpRequest.prototype.send;
+ XMLHttpRequest.prototype.open = function () {
+ const args = Array.prototype.slice.call(arguments, 0);
+ this.__args = args;
+ this.__reqId = args.slice(0, 2).join(':');
+ nativeXHROpen.apply(this, arguments);
+ };
+ XMLHttpRequest.prototype.send = function (data) {
+ console.log(this);
+ pendingXHRMap.set(this.__reqId, this);
+ parent.postMessage(
+ {
+ evt: 'requestProxy',
+ args: this.__args,
+ reqId: this.__reqId,
+ body: data
+ },
+ '*'
+ );
+ };
+
window.addEventListener('message', handleMessage, false);
window.addEventListener('error', function () {
sendMessage({ evt: 'error' });
diff --git a/src/editor/sandbox/worker.js b/src/editor/sandbox/worker.js
new file mode 100644
index 0000000..509ef17
--- /dev/null
+++ b/src/editor/sandbox/worker.js
@@ -0,0 +1,17 @@
+self.addEventListener('message', (e) => {
+ const { reqId, args, body } = e.data;
+ console.log('worker received xhr task', args);
+ const xhr = new XMLHttpRequest();
+ xhr.open.apply(xhr, args);
+ // PENDING
+ xhr.responseType = 'arraybuffer';
+ xhr.onload = xhr.onerror = (e) => {
+ console.log('worker xhr task result', e.type, e);
+ self.postMessage({
+ res: xhr.response,
+ reqId,
+ type: e.type
+ });
+ };
+ xhr.send(body);
+});