如何从 JavaScript 获取复制的文本

Fin*_*inn 5 javascript clipboard copy

这个问题与我问的另一个问题相关,但我意识到该问题中的一个附带问题值得有自己的问题。

使用 JavaScript,我想查看用户从网页复制的内容。当用户粘贴时,读取剪贴板内容相当容易:

document.addEventListener("paste", e => {
  let text = e.clipboardData.getData("text");
  alert("pasting text: " + text);
});
Run Code Online (Sandbox Code Playgroud)

这会正确地创建带有刚刚粘贴的内容的警报。然而,当用户进行复制时,获取剪贴板数据会更加困难。

方法1(无效)

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

这会警告“正在复制数据:”,但后面没有任何文本。那是因为该getData方法正在返回""(空字符串)。我的理解是,当您执行粘贴以外的任何操作时,网站读取您的剪贴板会被认为是一个太大的安全问题。

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

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

这是可行的,但在发出警报之前,它会创建一个弹出窗口,请求网站读取剪贴板的权限。我不想有这个弹出窗口。

方法3(看似可行,但似乎不太对)

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

这似乎是我想要的。允许这样做似乎很奇怪,但方法 1 却不允许。

我有一些问题:

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

此时,我只关心 Google Chrome 或 Chromium 上下文中的这些答案,而不关心其他浏览器。如果能回答任何这些问题,我们将不胜感激。

tho*_*ace 2

tl;dr如果您确实认为不诚实地告诉用户您正在做的事情是合理的,请使用方法 3 - 这是一个很好的解决方法,尽管许多人可能认为这是一种漏洞。

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

了解了这一点,我们可以得出一些结论:

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