fix: 在非安全上下文中为 copyMessage 添加 execCommand 备用方案#7747
fix: 在非安全上下文中为 copyMessage 添加 execCommand 备用方案#7747RC-CHN merged 2 commits intoAstrBotDevs:masterfrom
Conversation
在非安全上下文中(例如通过 HTTP 局域网 IP 访问),navigator.clipboard 不可用。为此,我们添加了使用 document.execCommand(‘copy’) 的备用方案,这与 ReadmeDialog.vue 和 Settings.vue 中的现有实现保持一致。
There was a problem hiding this comment.
Code Review
This pull request introduces a fallback mechanism for copying text to the clipboard using a hidden textarea when the Clipboard API is unavailable or the context is insecure. Feedback suggests making the fallback implementation more robust by using fixed positioning and read-only attributes, refactoring it into a shared utility to eliminate code duplication, and adding error handling to the primary Clipboard API call to ensure the fallback is triggered upon failure.
| function tryFallbackCopy(text: string) { | ||
| const textArea = document.createElement("textarea"); | ||
| textArea.value = text; | ||
| Object.assign(textArea.style, { | ||
| position: "absolute", | ||
| opacity: "0", | ||
| zIndex: "-1", | ||
| }); | ||
| document.body.appendChild(textArea); | ||
| textArea.select(); | ||
| document.execCommand("copy"); | ||
| document.body.removeChild(textArea); | ||
| } |
There was a problem hiding this comment.
建议优化 tryFallbackCopy 的实现并考虑将其提取为公共工具函数。设置 readOnly 可以防止在移动设备上弹出虚拟键盘,使用 position: fixed 并将其移出可视区域比 position: absolute 更稳健,能有效避免页面滚动或布局抖动。此外,PR 描述提到此逻辑在 ReadmeDialog.vue 和 Settings.vue 中也有重复,建议根据通用规则将其重构为共享函数以提高可维护性。
function tryFallbackCopy(text: string) {
const textArea = document.createElement("textarea");
textArea.value = text;
textArea.readOnly = true;
Object.assign(textArea.style, {
position: "fixed",
left: "-9999px",
top: "0",
});
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand("copy");
} catch (err) {
console.error("Fallback copy failed:", err);
} finally {
document.body.removeChild(textArea);
}
}
References
- 当在不同场景下实现类似功能时,应将逻辑重构为共享的辅助函数以避免代码重复。
| if (navigator.clipboard && window.isSecureContext) { | ||
| await navigator.clipboard.writeText(text); | ||
| } else { | ||
| tryFallbackCopy(text); | ||
| } |
There was a problem hiding this comment.
即使在安全上下文中,navigator.clipboard.writeText 也可能因为用户拒绝权限或其他运行时错误而失败。建议增加错误处理,确保在 Clipboard API 抛出异常时也能回退到 tryFallbackCopy。
if (navigator.clipboard && window.isSecureContext) {
try {
await navigator.clipboard.writeText(text);
return;
} catch (err) {
console.warn("Clipboard API failed, falling back:", err);
}
}
tryFallbackCopy(text);
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The new
tryFallbackCopyimplementation duplicates the existing clipboard fallback logic used inReadmeDialog.vueandSettings.vue; consider extracting a shared utility to avoid divergence between implementations. document.execCommand('copy')is deprecated and can fail silently; it may be worth wrappingtryFallbackCopyin a try/catch and optionally checking the boolean return value so the caller can handle failures more gracefully.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `tryFallbackCopy` implementation duplicates the existing clipboard fallback logic used in `ReadmeDialog.vue` and `Settings.vue`; consider extracting a shared utility to avoid divergence between implementations.
- `document.execCommand('copy')` is deprecated and can fail silently; it may be worth wrapping `tryFallbackCopy` in a try/catch and optionally checking the boolean return value so the caller can handle failures more gracefully.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
请注意添加测试截图,不包含测试的pr将不会被通过,本次暂且由我帮你测试,注意到该pr只能修复对于自行实现的复制部分在http连接情况下的fallback,对于你在issue中提到的情况,代码块由markstream-vue渲染,该pr无法处理在非安全连接情况下代码块的复制,请注意。 |
|
再度进行测试后注意到document.execCommand特性已被相当大一部分浏览器弃用 需要考虑最终fallback到框选区域由用户手动ctrl+c复制的方法 |
… and insecure contexts
|
感谢完善,学到了很多! |
… and insecure contexts (AstrBotDevs#7747) * fix: 在非安全上下文中为 copyMessage 添加 execCommand 备用方案 在非安全上下文中(例如通过 HTTP 局域网 IP 访问),navigator.clipboard 不可用。为此,我们添加了使用 document.execCommand(‘copy’) 的备用方案,这与 ReadmeDialog.vue 和 Settings.vue 中的现有实现保持一致。 * fix: extract shared clipboard utility and fix copy actions in dialogs and insecure contexts --------- Co-authored-by: RC-CHN <1051989940@qq.com>



在非安全上下文中(例如通过 HTTP 局域网 IP 访问),navigator.clipboard 不可用。为此,我们添加了使用 document.execCommand(‘copy’) 的备用方案,这与 ReadmeDialog.vue 和 Settings.vue 中的现有实现保持一致。
Fixes #7739
Modifications / 改动点
Screenshots or Test Results / 运行截图或测试结果
由于代码运行在 Docker 容器内,无法直接修改编译后的文件进行测试。
Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by Sourcery
Bug Fixes: