From e826540d2a91eb1391d960e2733e61c871ec58ed Mon Sep 17 00:00:00 2001 From: laoyang Date: Tue, 27 Oct 2026 01:00:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20PDF=20=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E8=A2=AB=20Chromium=20=E5=B1=8F=E8=94=BD=EF=BC=88iframe=20sand?= =?UTF-8?q?box=20=E7=A6=81=E7=94=A8=E5=86=85=E7=BD=AE=E9=98=85=E8=AF=BB?= =?UTF-8?q?=E5=99=A8=EF=BC=89=20#14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:资源模块点开 PDF 附件,预览区只剩「此页面已被 Chromium 屏蔽」。 根因:preview.js 的 pdf 分支给 iframe 挂了 sandbox (allow-same-origin allow-scripts,引入于 v24 8f80f3e)。 Chromium 只要看到 iframe 上有 sandbox 属性就禁用内置 PDF 阅读器插件, 表现即「被屏蔽」。五组同源对照实测(Chromium 153): · 无 sandbox → 正常渲染 · allow-same-origin allow-scripts → 屏蔽 · allow-scripts → 屏蔽 · + allow-popups-to-escape-sandbox→ 仍然屏蔽(网上答案说能救,本版本不行) · + allow-forms allow-popups → 仍然屏蔽 ⇒ 加白名单无效,只能不加。 改动:删掉该 setAttribute,换成 17 行实测结论注释防止以后被"为安全"加回去。 安全性说明:PDF 由浏览器内置阅读器扩展在独立扩展进程渲染,不是普通页面 上下文,拿不到父页 window/DOM/cookie;PDF 是原生文档,没有能访问父页的 脚本环境。服务端另有 nosniff + MIME 内容嗅探(media.php),PDF 不会被当 HTML 执行。若将来要禁止 PDF 内嵌 JS,正确做法是换 pdf.js 自渲染。 验证: · 新增 _tooling/_pdf_e2e.py,11 条断言全通过 0 失败,已登记进流水线 (挂「全路由」标签)。判据落在渲染层:frame 列表无 chrome-error、 有内置阅读器扩展 frame、iframe 内文字不含「屏蔽」。 · 反向验证:注入 sandbox 回去 → 4 条转红;恢复后 11/0。红绿闭环成立。 · 全量流水线 2h21m 跑完,EXIT=0,已部署。 · 线上 md5 与本地一致(988b804f),setAttribute('sandbox' 已不存在。 --- assets/js/preview.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/assets/js/preview.js b/assets/js/preview.js index 85c382d..984ab18 100644 --- a/assets/js/preview.js +++ b/assets/js/preview.js @@ -86,8 +86,23 @@ el = document.createElement('iframe'); el.className = 'pv-pdf'; el.src = src; - // PDF 是"另一份文档",别让它拿到本页的 window - el.setAttribute('sandbox', 'allow-same-origin allow-scripts'); + // ⚠️ 这里**绝对不能**加 sandbox 属性。加上去 PDF 会直接打不开: + // 页面只剩一行「此页面已被 Chromium 屏蔽」,阅读器根本不起。 + // + // 实测(Chromium 153,五组同源对照): + // · 无 sandbox → 正常渲染(多挂一个内置阅读器扩展 frame) + // · allow-same-origin allow-scripts → 屏蔽 + // · allow-scripts → 屏蔽 + // · + allow-popups-to-escape-sandbox → **仍然屏蔽**(网上很多答案说这个能救,本版本不行) + // · + allow-forms allow-popups → 仍然屏蔽 + // ⇒ 只要属性存在就不给 PDF 插件权限。加白名单无效,只能不加。 + // + // 不加也安全:PDF 由浏览器内置阅读器(mhjfbmdgcfjbbpaeojofohoefgiehjai) + // 在**独立扩展进程**里渲染,不是普通页面上下文,拿不到父页的 window / DOM / cookie。 + // PDF 是原生文档、不是 HTML,本就没有能访问父页面的脚本环境。 + // 服务端另有 `X-Content-Type-Options: nosniff` + MIME 按内容嗅探(media.php), + // PDF 不会被当 HTML 执行。若将来真需要禁止 PDF 内嵌 JS,正确做法是换 pdf.js 自渲染, + // 而不是给 iframe 挂 sandbox——那会把整个 PDF 预览一起废掉。 } else { el = document.createElement('img'); el.className = 'pv-img';