diff --git a/web/frontend/src/pages/CookiePage.tsx b/web/frontend/src/pages/CookiePage.tsx index c49a788..0becb5e 100644 --- a/web/frontend/src/pages/CookiePage.tsx +++ b/web/frontend/src/pages/CookiePage.tsx @@ -8,6 +8,30 @@ import { getErrorMessage } from '../utils/error'; const { Text } = Typography; +/** 复制文本到剪贴板,兼容非安全上下文(http://非localhost) */ +function copyToClipboard(text: string): Promise { + if (navigator.clipboard?.writeText) { + return navigator.clipboard.writeText(text); + } + // fallback:利用 textarea + execCommand,兼容 http 远程访问 + return new Promise((resolve, reject) => { + const ta = document.createElement('textarea'); + ta.value = text; + ta.style.position = 'fixed'; + ta.style.left = '-9999px'; + document.body.appendChild(ta); + ta.select(); + try { + const ok = document.execCommand('copy'); + document.body.removeChild(ta); + ok ? resolve() : reject(new Error('execCommand copy failed')); + } catch (e) { + document.body.removeChild(ta); + reject(e); + } + }); +} + export default function CookiePage() { const { token } = theme.useToken(); const [cookies, setCookies] = useState([]); @@ -55,7 +79,7 @@ export default function CookiePage() { message.warning('Cookie 为空'); return; } - navigator.clipboard.writeText(cookie).then(() => { + copyToClipboard(cookie).then(() => { message.success(`已复制 ${username} 的 Cookie`); }).catch(() => { message.error('复制失败'); @@ -71,7 +95,7 @@ export default function CookiePage() { const text = selected .map((c) => `${c.account_username}: ${c.cookie || '(空)'}`) .join('\n'); - navigator.clipboard.writeText(text).then(() => { + copyToClipboard(text).then(() => { message.success(`已复制 ${selected.length} 条 Cookie`); }).catch(() => { message.error('复制失败');