Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions dashboard/src/views/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,51 @@ const loadApiKeys = async () => {
}
};

const tryExecCommandCopy = (text) => {
let textArea = null;
try {
if (typeof document === 'undefined') return false;
textArea = document.createElement('textarea');
textArea.value = text;
textArea.setAttribute('readonly', '');
textArea.style.position = 'fixed';
textArea.style.opacity = '0';
textArea.style.pointerEvents = 'none';
textArea.style.left = '-9999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
textArea.setSelectionRange(0, text.length);
return document.execCommand('copy');
Comment on lines +339 to +351
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

推荐创建完元素复制好删一下(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的,待会会一起加上,感谢建议

} catch (_) {
return false;
} finally {
try {
textArea?.remove?.();
} catch (_) {
// ignore cleanup errors
}
}
};

const copyTextToClipboard = async (text) => {
if (!text) return false;
if (tryExecCommandCopy(text)) return true;
if (typeof navigator === 'undefined' || !navigator.clipboard?.writeText) return false;
try {
await navigator.clipboard.writeText(text);
return true;
} catch (_) {
return false;
}
};
Comment on lines +363 to +373
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

copyTextToClipboard 函数目前的实现优先使用了已废弃的 document.execCommand('copy') 方法,而不是现代的 navigator.clipboard.writeText() API。最佳实践是,当现代的、更安全、异步的 Clipboard API 可用时,应优先使用它,仅在旧版浏览器或非安全上下文中才回退到 execCommand

建议调整逻辑,首先尝试使用 navigator.clipboard.writeText() 进行复制,如果失败或不可用,再回退到 tryExecCommandCopy。这能提高代码的可维护性,并与现代 Web 开发实践保持一致。

const copyTextToClipboard = async (text) => {
    if (!text) return false;
    if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
        try {
            await navigator.clipboard.writeText(text);
            return true;
        } catch (err) {
            // Modern API failed, fall back to legacy.
            console.warn('Clipboard API failed, falling back to execCommand.', err);
        }
    }
    return tryExecCommandCopy(text);
};


const copyCreatedApiKey = async () => {
if (!createdApiKeyPlaintext.value) return;
try {
await navigator.clipboard.writeText(createdApiKeyPlaintext.value);
const ok = await copyTextToClipboard(createdApiKeyPlaintext.value);
if (ok) {
showToast(tm('apiKey.messages.copySuccess'), 'success');
} catch (_) {
} else {
showToast(tm('apiKey.messages.copyFailed'), 'error');
}
};
Expand Down