如何从 JavaScript 中获取复制的文本

How to get copied text from JavaScript

此问题与 another question I asked 有关,但我意识到该问题中的一个附带问题值得单独提问。

使用 JavaScript,我想查看用户从网页复制的内容。当用户 粘贴:

时,读取剪贴板内容相当容易
document.addEventListener("paste", e => {
  let text = e.clipboardData.getData("text");
  alert("pasting text: " + text);
});

这会正确地创建一个包含刚刚粘贴的内容的警报。但是,当用户 复制.

时,获取剪贴板数据会更加困难

方法一(无效)

document.addEventListener("copy", e => {
  let text = e.clipboardData.getData("text");
  alert("copying text: " + text);
});

这会提醒 "copying data: " 但后面没有任何文字。那是因为 getData 方法返回 ""(空字符串)。我的理解是,当您执行粘贴以外的任何操作时,网站读取您的剪贴板会被认为是一个严重的安全问题。

方法 2(可行,但有弹出窗口)

document.addEventListener("copy", () => {
  navigator.clipboard.readText().then(text => alert("copied text: " + text));
});

这有效,但在发出警报之前,它会创建一个弹出窗口,请求允许网站读取剪贴板。我宁愿没有这个弹出窗口。

方法三(好像可以,但好像不太对)

document.addEventListener("copy", () => {
  let text = window.getSelection().toString();
  alert("copying text: " + text);
});

这似乎符合我的要求。允许这样做似乎很奇怪,但方法 1 不允许。

我有几个问题:

  1. 如果方法 3 允许,为什么方法 1 不允许?方法一似乎可以提供与方法三相同的信息,而且更方便,同样安全。
  2. 在某些情况下,方法 3 会提供与方法 2 不同的结果(就 text 变量而言,而不是弹出行为)?
  3. 使用方法 3 是否还有其他我没有考虑到的缺点?

在这一点上,我只关心 Google Chrome 或 Chromium 上下文中的这些答案,而不关心其他浏览器。任何这些问题的答案将不胜感激。

tl;dr 如果您真的认为不向用户诚实说明您正在做的事情是合理的,请使用方法 3 - 这是一个很好的解决方法,尽管许多人可能会考虑这是一个漏洞。

查看 W3 规范 (https://www.w3.org/TR/clipboard-apis/#Cases),我们可以深入了解为什么这些事件(以及仍在开发中的 API)首先存在。具体来说,copy 可以让您 更改 在您的目标不是用户实际希望最终出现在剪贴板上的内容的情况下复制的内容,而 paste 的存在是为了让您处理将该数据传输到您的应用程序中。

知道了这些,我们可以得出一些结论:

  • 方法 1:该规范没有详细介绍剪贴板安全性,只是说明实现应该能够保护用户。因此,复制的数据对您是隐藏的,我并不感到惊讶;这似乎是实施者的明智决定。更重要的是,查看规范规定的算法,很可能 剪贴板中还没有数据,因为此事件的目的是让您设置应该 结束他们的生活。
  • 方法二:这似乎更符合作者的意图。 如果 一个应用程序要访问剪贴板,它真的应该得到用户的许可。特别是因为剪贴板可能包含来自页面外部的数据。
  • 方法3:这是一个漏洞,但很难看到它不起作用的情况。从实施者的角度来看,很难阻止——因为他们必须检查事件委托函数的调用;与 'not making the data readily available' 相比。它也可以说是安全的足够,因为您可以访问的唯一信息是已经在您自己的文档.
  • 上的信息