HTML5可以用来替代基于Flash的ZeroClipboard,安全地复制数据到剪贴板吗?

64
随着Flash在许多环境中逐渐退出(iPhone、Android、IE10等),是否有任何新的解决方案在任何浏览器中即使没有安装Flash也能够安全地复制信息到剪贴板?
到目前为止,我一直在使用ZeroClipboard,但我担心更多的观众没有安装Flash,这个功能将会失效,我希望尽可能不依赖Flash。

3
有一个来自W3C WebApps WG的Clipboard API,但我不认为它已经被实现了。让Web应用程序访问用户的剪贴板涉及到大量的安全问题。 - steveax
2
@steveax - 我以前见过这个。它在哪里实现了吗?我也知道安全影响,但是Flash设法通过要求用户操作来展示一些功能。 - jfriend00
https://cbabhusal.wordpress.com/2015/11/15/ror-copy-some-arbitrary-text-into-users-clipboard/ - Shiva
6个回答

20
翻译:这是因为自动复制到剪贴板可能非常危险,因此大多数浏览器(除了IE)*会使其变得困难,除非您使用flash。
与您的ZeroClipboard类似,还有Clipboard LMCButton,它也使用在后台运行的小型flash脚本。
一个常见的解决方案是这样做:
 function copyToClipboard (text) {
     window.prompt ("Copy to clipboard: Ctrl+C, Enter", text);
 }

这段文字是从Jarek Milewski那里得到的,当时有人在这里提出了问题

*我找到了一个在IE中可行的解决方案,但在大多数现代浏览器中不起作用,请查看此处

更新:

根据https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand,Firefox 41+、Chrome 42+和IE 9+支持使用execCommand复制命令。对于Firefox和Chrome,只有在用户操作(例如单击)触发时才会起作用;对于IE,则会弹出警告对话框,要求用户允许将内容复制到剪贴板。


7
如果我们可以通过Flash实现,那么为什么通过HTML5实现就会成为安全隐患?从剪贴板读取肯定是不安全的,但是将写入剪贴板称为安全漏洞似乎有些牵强,因为它需要用户实际上将其粘贴到危险的地方。 - freeall
5
我同意从剪贴板复制内容可能存在安全问题,但我认为将其写入并不是。毕竟,用户需要将其粘贴到某个地方,然后可能还需要执行另一个操作才能真正发送/执行它。我认为这并不比我在我的网站上写一段文本“请复制 'rm /* --recursive'(你知道我的意思),并要求用户执行”更具威胁性。 - freeall
21
就这样结束吧... :) 如果我们作为网页开发者能够在Flash中做一些事情,那么我认为我们也应该允许自己在HTML(5)中做同样的事情。如果这是一个漏洞,那么它已经存在于可能超过95%的浏览器中,所以我们并没有打开新的漏洞,而那些想要利用它的人仍然可以在Flash中进行,只不过不能在HTML(5)中进行。 - freeall
9
如果我之前切掉了重要信息,而且任何网站都可以覆盖我的剪贴板,那就会导致我丢失信息。这是一个安全漏洞。 - WhyNotHugo
4
许多用户最初就不安装Flash并避免这些安全漏洞。将其改为标准的HTML5会将此问题强加给所有人,而浏览器供应商实际上足够关心以避免添加安全漏洞。 - WhyNotHugo
显示剩余11条评论

19

我知道这个答案有点晚了,但现在有一个新的现代化替代方案可以代替基于Flash的ZeroClipboard。 Clipboard.js 是一个2kB纯JavaScript的替代品,没有任何依赖。


1
具有讽刺意味的是,此插件不支持移动或桌面版Safari,因此我们无法支持iOS。 - Daniel Nalbach

8

我创建了一个名为clip-j的纯JavaScript解决方案。 这里 是它的代码。基本上它利用了document.execCommand('copy');和其他几个命令,使你看不到任何东西。以下是代码:

function clip(text) {   
    var copyElement = document.createElement('input');      
    copyElement.setAttribute('type', 'text');   
    copyElement.setAttribute('value', text);    
    copyElement = document.body.appendChild(copyElement);   
    copyElement.select();   
    document.execCommand('copy');   
    copyElement.remove();
}

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。 - Kenster
谢谢你的提示!我会修复它。 - Triforcey
这仅在最新的浏览器中支持。 更多信息请参见 https://cbabhusal.wordpress.com/2015/11/15/ror-copy-some-arbitrary-text-into-users-clipboard/ - Shiva
1
为什么这可能是真的,很快最新的浏览器将成为介质。这是一个简单的解决方案,我承认它超前了,但随着时间的推移和更多的人更新,它变得更有用。 - Triforcey
如果您使用带有contentEditable属性设置为truediv(而不是input),则还可以将其作为text/html复制到剪贴板中,从而保留格式。请参见此答案:https://dev59.com/SWEh5IYBdhLWcg3wTB1c#30905277 - Krisztián Balla

3
您可以查看这篇博客文章,深入讨论如何在HTML5中使用剪贴板。不幸的是,您仍然无法在单击时将内容复制到剪贴板上。但是,对于Chrome和Firefox,您可以创建一个浏览器扩展程序,可以授予您的站点访问剪贴板的权限,我相信IE会允许您将内容复制到剪贴板上,但会提示用户授权。 更新
根据此文献:https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand Firefox 41+、Chrome 42+和IE 9+支持使用execCommand复制命令。对于Firefox和Chrome,它只能在用户操作(例如单击)触发时起作用,而对于IE,则会弹出警告对话框,要求用户授权复制到剪贴板。

0

这个问题有很棒的答案在这里, 而我选择使用这段代码:

function copyToClipboard(element) {
    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val($(element).text()).select();
    document.execCommand("copy");
    $temp.remove();
}

然而,如果您的页面上有bootstrap-select,那么$temp.val($(element).text()).select()这行代码将会抛出一个错误:

该小部件只能在选择元素上工作

您可以像jQuery文档中的.select()所述,使用.trigger('select')代替,像这样:
$temp.val($(element).val()).trigger('select');

0
要使用execCommand,您必须首先在页面上选择()某些内容,这样您就不会只复制最后放入剪贴板的任何内容。通过此函数,我将输入文本框的ID传递到函数中并进行选择(),然后执行复制命令。无需添加侦听器或进一步复杂化代码。如果未启用或支持,则document.execCommand()返回false,因此您可以使用window.prompt作为备份方法。
function copyToClipboard(id) {
    var blnCopied;
    document.getElementById(id).select();
    blnCopied = document.execCommand("copy", false, null);
    if (blnCopied)
        alert('Link copied to clipboard');
    else
        window.prompt ("Copy to clipboard: Ctrl+C, Enter", jQuery("#"+id).val());
}

使用标准的“a”锚点标签,并添加onclick="copyToClipboard('some_id')"属性


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接