-
-
Notifications
You must be signed in to change notification settings - Fork 182
Open
Description
我采用 blob+iframe 的形式在本地运行,但无法查看网页源代码。
报错
common.js:1 Uncaught (in promise) SecurityError: Failed to construct 'Worker': Script at 'https://cdn.jsdelivr.net/npm/chii/public/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.js' cannot be accessed from origin 'http://localhost:3000'.
at common.js:1:95943
at new Promise (<anonymous>)
at new pr (common.js:1:95918)
at pr.fromURL (common.js:1:96079)
at s.createWorker (formatter.js:1:328)
at s.processNextTask (formatter.js:1:689)
at formatter.js:1:1541
at new Promise (<anonymous>)
at s.runTask (formatter.js:1:1472)
at s.format (formatter.js:1:1634)
(anonymous) @ common.js:1
pr @ common.js:1
fromURL @ common.js:1
createWorker @ formatter.js:1
processNextTask @ formatter.js:1
(anonymous) @ formatter.js:1
runTask @ formatter.js:1
format @ formatter.js:1
h @ formatter.js:1
setPretty @ source_frame.js:1
setDeferredContent @ source_frame.js:1
await in setDeferredContent
ensureContentLoaded @ source_frame.js:1
wasShown @ source_frame.js:1
wasShown @ sources.js:1
notify @ legacy.js:1
processWasShown @ legacy.js:1
showWidgetInternal @ legacy.js:1
show @ legacy.js:1
showTab @ legacy.js:1
selectTab @ legacy.js:1
innerShowFile @ sources.js:1
showFile @ sources.js:1
showSourceLocation @ sources.js:1
showUISourceCode @ sources.js:1
reveal @ sources.js:1
(anonymous) @ common.js:1
jt @ common.js:1
await in jt
sourceSelected @ sources.js:1
onclick @ sources.js:1
报错说是因为安全问题无法在 localhost 中创建 cdn 的 worker?是否可以通过 blob 的方式创建 worker?
源码
<body>
<script src="https://cdn.jsdelivr.net/npm/chobitsu"></script>
<script>太长 写在下面</script>
<script src="/src/index.jsx" type="module"></script>
↑ vite 出来的带 source map 的代码
</body>// 参考:
// https://github.com/solidjs/solid-playground/blob/master/packages/solid-repl/src/components/preview.tsx
// https://github.com/liriliri/chii/blob/master/src/target/DevtoolsFrame.ts
function devToolsSrc(targetOrigin = location.origin) {
const version = '';
const cdn = `https://cdn.jsdelivr.net/npm/chii${version? '@' + version: ''}/public`;
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
const html = `
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<title>DevTools</title>
<style>
@media (prefers-color-scheme: dark) {
body {
background-color: #292a2d;
}
}
body .screencast-viewport {
max-width: 100%;
flex: 1;
}
</style>
${isSafari? `<script src="${cdn}/front_end/third_party/polyfill/customElement.js"></scr`+`ipt>`: ''}
${!window.requestIdleCallback? `<script src="${cdn}/front_end/third_party/polyfill/requestIdleCallback.js"></scr`+`ipt>`: ''}
<meta name="referrer" content="no-referrer">
<script src="https://unpkg.com/@ungap/custom-elements/es.js"></scr`+`ipt>
<script type="module" src="${cdn}/front_end/entrypoints/chii_app/chii_app.js"></scr`+`ipt>
<body class="undocked" id="-blink-dev-tools">
`;
const devtoolsRawUrl = URL.createObjectURL(new Blob([html], { type: 'text/html' }));
// URL.revokeObjectURL(devtoolsRawUrl);
return `${devtoolsRawUrl}#?embedded=${encodeURIComponent(targetOrigin)}`;
}
const windowLoaded = new Promise((s) => window.addEventListener('load', s));
async function openDevTools() {
const targetOrigin = location.origin;
const devtoolsIframe = document.createElement('iframe');
devtoolsIframe.setAttribute('title', 'DevTools');
devtoolsIframe.style.border = "none";
devtoolsIframe.style.height = '50vh';
devtoolsIframe.style.width = '100vw';
devtoolsIframe.style.position = 'fixed';
devtoolsIframe.style.bottom = '0';
devtoolsIframe.style.left = '0';
devtoolsIframe.style.zIndex = 9e20 + '';
devtoolsIframe.src = devToolsSrc(targetOrigin);
document.body.appendChild(devtoolsIframe);
let devtoolsLoaded = false;
const runtimeExeCtxCreated = Promise.withResolvers();
// 这里等待 devtools 加载完毕再输出,才能保证输出的信息不会丢失
// 而目前观察到的只有接受到frameTree之后才能正常输出
// 故而这里缓存所有的控台输出,等待frameTree之后再输出
const msgBuffer = [];
const sendToDevtools = (msg, force = false) => {
if (typeof msg !== 'string') msg = JSON.stringify(msg);
if (!devtoolsLoaded && msg.includes('frameTree')) {
runtimeExeCtxCreated.resolve();
}
if (!force && !devtoolsLoaded && (
msg.includes('Runtime.consoleAPICalled')
|| msg.includes('Runtime.exceptionRevoked')
|| msg.includes('Runtime.exceptionThrown')
// || msg.includes('Runtime.executionContextCreated')
// || msg.includes('Runtime.executionContextDestroyed')
// || msg.includes('Runtime.executionContextsCleared')
// || msg.includes('Runtime.inspectRequested')
// || msg.includes('Runtime.bindingCalled')
))
msgBuffer.push(msg);
else devtoolsIframe.contentWindow.postMessage(msg, targetOrigin);
};
let id = 0;
const sendToChobitsu = (msg) => {
msg.id = 'tmp' + ++id;
chobitsu.sendRawMessage(JSON.stringify(msg));
};
chobitsu.setOnMessage((message) => {
if (message.includes('"id":"tmp')) return;
sendToDevtools(message);
});
runtimeExeCtxCreated.promise.then(async () => {
for (let i = 0; i < msgBuffer.length; ++i)
sendToDevtools(msgBuffer[i], true);
devtoolsLoaded = true;
msgBuffer.length = 0;
});
sendToDevtools({
method: 'Page.frameNavigated',
params: {
frame: {
id: '1',
mimeType: 'text/html',
securityOrigin: location.origin,
url: location.href,
},
type: 'Navigation',
},
});
sendToChobitsu({ method: 'Network.enable' });
sendToDevtools({ method: 'Runtime.executionContextsCleared' });
sendToChobitsu({ method: 'Runtime.enable' });
sendToChobitsu({ method: 'Debugger.enable' });
sendToChobitsu({ method: 'DOMStorage.enable' });
sendToChobitsu({ method: 'DOM.enable' });
sendToChobitsu({ method: 'CSS.enable' });
sendToChobitsu({ method: 'Overlay.enable' });
sendToChobitsu({ method: 'Console.enable' });
sendToDevtools({ method: 'DOM.documentUpdated' });
window.addEventListener('message', ({ source, data }) => {
if (source === devtoolsIframe.contentWindow) {
chobitsu.sendRawMessage(data);
}
});
}
openDevTools();Metadata
Metadata
Assignees
Labels
No labels