From fe81c879b0b699e66ed6cd795696e372f71a4d0c Mon Sep 17 00:00:00 2001 From: Victor_Jay Date: Thu, 28 May 2026 15:21:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=9D=97=E8=AF=AD=E6=B3=95=E9=AB=98=E4=BA=AE=E4=B8=A2=E5=A4=B1?= =?UTF-8?q?=20+=20=E8=AF=AD=E8=A8=80=E6=A0=87=E7=AD=BE=E6=B3=A8=E5=85=A5?= =?UTF-8?q?=20+=20=E5=AE=89=E5=85=A8=E6=80=A7=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 cdnjs.cloudflare.com CSP 白名单,允许加载 highlight.js - 消毒策略放行 span 元素,保留 highlight.js 高亮 class - 详情页和新帖子页引入 highlight.js 库和 GitHub 主题 - 代码块语言选择器默认 text,支持 prev/next 循环切换语言 - 代码块语言标签注入兼容 data-language 和 code class 双来源 - 修复 utils.js defer 导致 common.js 执行时 getCSRFToken 未定义 --- internal/middleware/security.go | 8 +- internal/service/post_service.go | 3 +- templates/MetaLab-2026/html/posts/new.html | 180 --------- templates/MetaLab-2026/html/posts/show.html | 31 +- templates/MetaLab-2026/static/css/posts.css | 382 +++++++++++++------- templates/MetaLab-2026/static/js/editor.js | 49 ++- 6 files changed, 305 insertions(+), 348 deletions(-) diff --git a/internal/middleware/security.go b/internal/middleware/security.go index 34204ce..41685fb 100644 --- a/internal/middleware/security.go +++ b/internal/middleware/security.go @@ -9,14 +9,14 @@ import ( func SecurityHeaders() gin.HandlerFunc { return func(c *gin.Context) { // Content-Security-Policy - // script-src: 本站 + esm.sh CDN (Tiptap ESM 模块) - // style-src: 本站 + esm.sh (Tiptap CSS) + // script-src: 本站 + esm.sh CDN (Tiptap ESM 模块) + cdnjs (highlight.js) + // style-src: 本站 + esm.sh (Tiptap CSS) + cdnjs (highlight.js 主题) // connect-src: 本站 + esm.sh (source map 请求) // img-src: 本站 + data: URI (头像裁切) + blob: (粘贴图片) c.Header("Content-Security-Policy", "default-src 'self'; "+ - "script-src 'self' 'unsafe-inline' https://esm.sh; "+ - "style-src 'self' 'unsafe-inline' https://esm.sh; "+ + "script-src 'self' 'unsafe-inline' https://esm.sh https://cdnjs.cloudflare.com; "+ + "style-src 'self' 'unsafe-inline' https://esm.sh https://cdnjs.cloudflare.com; "+ "img-src 'self' data: blob:; "+ "connect-src 'self' https://esm.sh") diff --git a/internal/service/post_service.go b/internal/service/post_service.go index f396eda..7214ef7 100644 --- a/internal/service/post_service.go +++ b/internal/service/post_service.go @@ -16,10 +16,11 @@ import ( // sanitizePolicy Tiptap 输出 HTML 的消毒策略 // 前端 WYSIWYG 编辑器输出 HTML,由 bluemonday UGC 策略消毒 // 放行 code/pre 的 class/data-language 属性以保留代码高亮和语言标签 -// 放行 span 的 class 属性以保留 highlight.js 的 hljs-* 高亮 +// 放行 span 元素及其 hljs-* class 以保留 highlight.js 语法高亮 // 放行 img 的 src/alt/title 属性以保留图片 var sanitizePolicy = func() *bluemonday.Policy { p := bluemonday.UGCPolicy() + p.AllowElements("span") p.AllowAttrs("class", "data-language").OnElements("code", "pre") p.AllowAttrs("class").Matching(regexp.MustCompile("^hljs-")).OnElements("span") p.AllowAttrs("src", "alt", "title").OnElements("img") diff --git a/templates/MetaLab-2026/html/posts/new.html b/templates/MetaLab-2026/html/posts/new.html index 4664828..5a62938 100644 --- a/templates/MetaLab-2026/html/posts/new.html +++ b/templates/MetaLab-2026/html/posts/new.html @@ -1,184 +1,4 @@ {{template "layout/header.html" .}} - {{template "layout/nav.html" .}} diff --git a/templates/MetaLab-2026/html/posts/show.html b/templates/MetaLab-2026/html/posts/show.html index 248a427..02361e8 100644 --- a/templates/MetaLab-2026/html/posts/show.html +++ b/templates/MetaLab-2026/html/posts/show.html @@ -1,4 +1,5 @@ {{template "layout/header.html" .}} + {{template "layout/nav.html" .}} @@ -45,18 +46,34 @@ {{template "layout/footer.html" .}} +