From fa3b20d1bc9591be568b9cb96a464234201ecc9e Mon Sep 17 00:00:00 2001 From: Victor_Jay Date: Tue, 2 Jun 2026 21:42:20 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=20CSP=20=E8=BF=9D=E8=A7=84?= =?UTF-8?q?=20=E2=80=94=20inline=20onclick/onerror=20=E7=A7=BB=E5=85=A5?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=A7=94=E6=89=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 审核操作按钮(通过/拒绝)从 onclick 替换为 data-audit-action 属性 + document 级事件委托 - 分页按钮从 onclick 替换为 data-go-page 属性 + 事件委托 - 头像加载失败处理从 inline onerror 替换为 data-fallback 标记 + addEventListener 绑定 --- templates/admin/static/js/audit.js | 52 ++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/templates/admin/static/js/audit.js b/templates/admin/static/js/audit.js index 1945d58..297e2cd 100644 --- a/templates/admin/static/js/audit.js +++ b/templates/admin/static/js/audit.js @@ -13,6 +13,34 @@ const pages = { }; let pendingRejectId = null; +// 审核操作按钮事件委托(避免 inline onclick) +function handleAuditClick(e) { + const btn = e.target.closest('[data-audit-action]'); + if (!btn) return; + const action = btn.dataset.auditAction; + const id = parseInt(btn.dataset.auditId); + if (action === 'approve') approveAudit(id); + else if (action === 'reject') openRejectModal(id); +} + +// 分页按钮事件委托 +function handlePaginationClick(e) { + const btn = e.target.closest('[data-go-page]'); + if (!btn) return; + goPage(parseInt(btn.dataset.goPage)); +} + +// 为动态插入的图片绑定 error 处理 +function attachImageErrorHandlers(container) { + if (!container) return; + container.querySelectorAll('img[data-fallback]').forEach(img => { + img.addEventListener('error', function handler() { + this.src = 'data:image/svg+xml,' + encodeURIComponent('加载失败'); + this.removeEventListener('error', handler); + }); + }); +} + document.addEventListener('DOMContentLoaded', () => { // TAB 切换 document.querySelectorAll('.audit-tab').forEach(tab => { @@ -26,6 +54,10 @@ document.addEventListener('DOMContentLoaded', () => { }); }); + // 全局事件委托:审核操作 & 分页 + document.addEventListener('click', handleAuditClick); + document.addEventListener('click', handlePaginationClick); + // 初始加载 loadCurrentTab(); }); @@ -122,8 +154,8 @@ function renderUsernameRow(item) { ${escapeHtml(item.new_value)} ${formatTime(item.created_at)} - - + + `; } @@ -137,8 +169,8 @@ function renderBioRow(item) { ${escapeHtml(display)} ${formatTime(item.created_at)} - - + + `; } @@ -161,14 +193,16 @@ function renderAvatarCards(items) {
新头像 → - 新头像 + 新头像
- - + +
`).join(''); + // 为动态插入的图片绑定 error 处理器(CSP 不允许 inline onerror) + attachImageErrorHandlers(grid); } /* ========================================= @@ -258,9 +292,9 @@ function renderPagination(total, page, barId) { const bar = document.getElementById(barId); if (totalPages <= 1) { bar.innerHTML = ''; return; } - let html = ``; + let html = ``; html += `第 ${page} / ${totalPages} 页(共 ${total} 条)`; - html += ``; + html += ``; bar.innerHTML = html; }