From 6701ddad55540b64afc679257a35dd76889be04f Mon Sep 17 00:00:00 2001 From: K-hermes Date: Sat, 15 Aug 2026 13:17:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20HTTP=20=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E4=B8=8B=E5=A4=8D=E5=88=B6=E5=8A=9F=E8=83=BD=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - navigator.clipboard 只在 HTTPS 下可用 - HTTP 环境(IP 访问)会报错 Cannot read properties of undefined 解决方案: - 创建兼容的 copyToClipboard 函数 - 优先尝试 navigator.clipboard (HTTPS) - 降级到 document.execCommand (HTTP 也可用) - 统一处理 copyJSON 和 copyConfig 两处复制功能 - 失败时提示用户手动复制 --- web/index.html | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/web/index.html b/web/index.html index d38b7d9..80e8dbb 100644 --- a/web/index.html +++ b/web/index.html @@ -676,14 +676,47 @@ } } + // 通用复制函数(兼容 HTTP 和 HTTPS) + function copyToClipboard(text) { + // 方法1: 尝试 navigator.clipboard (HTTPS) + if (navigator.clipboard && navigator.clipboard.writeText) { + return navigator.clipboard.writeText(text) + .then(() => true) + .catch(() => false); + } + + // 方法2: 使用传统的 execCommand (HTTP 也可用) + return new Promise((resolve) => { + const textarea = document.createElement('textarea'); + textarea.value = text; + textarea.style.position = 'fixed'; + textarea.style.left = '-9999px'; + textarea.style.top = '0'; + document.body.appendChild(textarea); + + try { + textarea.select(); + textarea.setSelectionRange(0, 99999); + const success = document.execCommand('copy'); + document.body.removeChild(textarea); + resolve(success); + } catch (err) { + document.body.removeChild(textarea); + resolve(false); + } + }); + } + // 复制 JSON function copyJSON() { if (currentViewData) { const text = JSON.stringify(currentViewData, null, 2); - navigator.clipboard.writeText(text).then(() => { - showToast('JSON 已复制到剪贴板'); - }).catch(() => { - showToast('复制失败', 'error'); + copyToClipboard(text).then((success) => { + if (success) { + showToast('JSON 已复制到剪贴板'); + } else { + showToast('复制失败,请手动选择复制', 'error'); + } }); } } @@ -694,8 +727,12 @@ const response = await fetch(`/api/data/copy/${tag}`); const data = await response.json(); - await navigator.clipboard.writeText(data.copy_text); - showToast('配置已复制到剪贴板'); + const success = await copyToClipboard(data.copy_text); + if (success) { + showToast('配置已复制到剪贴板'); + } else { + showToast('复制失败,请手动选择复制', 'error'); + } } catch (error) { showToast('复制失败:' + error.message, 'error'); }