zcbot/web/static/js/preview_content.js

34 lines
1.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 可独立测试的 HTML 预览安全策略。脚本和 HTTPS 外部资源可运行,满足图表、
// 地图、WebGL 等通用产物iframe 保持 opaque origin不能触达 zcbot 宿主权限。
// 使用同源静态宿主页 + postMessage而非 iframe.srcdoc / blob URL部分 WebView
// 对 srcdoc 支持不完整,原生壳的 URL 白名单又常会误拦 blob: 子 frame。
export const HTML_PREVIEW_CSP = "default-src 'none'; " +
"script-src 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval' https:; " +
"style-src 'unsafe-inline' https:; img-src data: blob: https:; " +
"media-src data: blob: https:; font-src data: https:; connect-src https:; " +
"worker-src blob:; child-src blob: https:; frame-src https:; manifest-src https:; " +
"object-src 'none'; form-action 'none'; base-uri 'none'";
export const HTML_PREVIEW_SANDBOX = "allow-scripts";
export const HTML_PREVIEW_HOST = "/static/html_preview_host.html";
export function htmlPreviewDocument(text) {
const meta = `<meta http-equiv="Content-Security-Policy" content="${HTML_PREVIEW_CSP}">`;
const source = String(text || "");
if (/<head(?:\s[^>]*)?>/i.test(source)) {
return source.replace(/<head(?:\s[^>]*)?>/i, (head) => head + meta);
}
return `<head>${meta}</head>${source}`;
}
export function configureHtmlPreviewFrame(frame, text, title = "HTML 文件预览") {
frame.title = title;
frame.setAttribute("sandbox", HTML_PREVIEW_SANDBOX);
frame.referrerPolicy = "no-referrer";
const document = htmlPreviewDocument(text);
frame.addEventListener("load", () => {
frame.contentWindow.postMessage({ type: "zcbot-html-preview", document }, "*");
}, { once: true });
frame.src = HTML_PREVIEW_HOST;
return frame;
}