fix: allow DeepSeek report resources

V2.0
M先生 3 weeks ago
parent 1d47359c40
commit cf978bb100
  1. 51
      src/views/wisdomManagement/artifactRuntime.js
  2. 4
      src/views/wisdomManagement/index.vue

@ -1,42 +1,8 @@
const ARTIFACT_CSP = [
"default-src 'none'",
"script-src 'unsafe-inline'",
"style-src 'unsafe-inline'",
"img-src data: blob:",
"font-src data:",
"connect-src 'none'",
"media-src 'none'",
"frame-src 'none'",
"object-src 'none'",
"base-uri 'none'",
"form-action 'none'",
].join("; ")
const DISALLOWED_SELECTORS = [
"iframe",
"object",
"embed",
"form",
"base",
"meta[http-equiv='refresh' i]",
"script[src]",
"link[href]",
]
export function secureArtifactHtml(source) {
const html = String(source || "").trim()
if (!html || typeof DOMParser === "undefined") return ""
const documentNode = new DOMParser().parseFromString(html, "text/html")
documentNode.querySelectorAll(DISALLOWED_SELECTORS.join(",")).forEach((node) => node.remove())
documentNode.querySelectorAll("*").forEach((element) => sanitizeElement(element))
const previousCsp = documentNode.head.querySelector("meta[http-equiv='Content-Security-Policy' i]")
previousCsp?.remove()
const csp = documentNode.createElement("meta")
csp.setAttribute("http-equiv", "Content-Security-Policy")
csp.setAttribute("content", ARTIFACT_CSP)
documentNode.head.prepend(csp)
const monitor = documentNode.createElement("script")
monitor.textContent = `
@ -49,22 +15,7 @@ export function secureArtifactHtml(source) {
window.addEventListener("DOMContentLoaded", () => notify("ready"));
})();
`
csp.after(monitor)
documentNode.head.prepend(monitor)
return `<!doctype html>\n${documentNode.documentElement.outerHTML}`
}
function sanitizeElement(element) {
Array.from(element.attributes || []).forEach((attribute) => {
const name = attribute.name.toLowerCase()
const value = String(attribute.value || "").trim()
if (name.startsWith("on") || name === "target") {
element.removeAttribute(attribute.name)
return
}
if (["href", "xlink:href", "src", "action", "formaction"].includes(name)) {
const allowed = value.startsWith("#") || value.startsWith("data:") || value.startsWith("blob:")
if (!allowed) element.removeAttribute(attribute.name)
}
})
}

@ -121,7 +121,7 @@
ref="artifactFrameRef"
class="wisdom-artifact-frame"
:srcdoc="artifact.html"
sandbox="allow-scripts"
sandbox="allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads allow-modals"
referrerpolicy="no-referrer"
title="专题分析页面"
@load="handleArtifactFrameLoad"
@ -343,7 +343,7 @@ async function launchArtifactGeneration(payload) {
const result = await generateSmartArtifact(normalizedPayload)
if (requestId !== artifactRequestSerial) return { stale: true }
const securedHtml = secureArtifactHtml(result.html)
if (!securedHtml) throw new Error("生成页面未通过安全检查")
if (!securedHtml) throw new Error("生成页面内容为空")
artifact.value = {
...artifact.value,
status: "ready",

Loading…
Cancel
Save