clipboard-copy vs clipboard-polyfill
Web 剪贴板操作库对比
clipboard-copyclipboard-polyfill类似的npm包:

Web 剪贴板操作库对比

clipboard-copyclipboard-polyfill 都是用于在 Web 应用中实现文本复制到系统剪贴板功能的 JavaScript 库。它们都基于现代 navigator.clipboard API 封装,但采取了截然不同的兼容性策略:clipboard-copy 仅提供对现代浏览器的简单封装,不包含任何降级逻辑;而 clipboard-polyfill 则是一个完整的 polyfill,能在不支持现代 API 的旧浏览器中自动回退到基于 document.execCommand 的模拟方案,并额外支持富文本复制和剪贴板读取等高级功能。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
clipboard-copy0634-76 年前MIT
clipboard-polyfill0927404 kB91 年前MIT

clipboard-copy vs clipboard-polyfill:现代 Web 剪贴板操作的两种实现路径

在前端开发中,将文本复制到系统剪贴板是一个常见需求,比如“一键复制链接”、“复制验证码”等。然而,由于浏览器安全策略限制,document.execCommand('copy') 已被废弃,现代方案应基于 navigator.clipboard API。clipboard-copyclipboard-polyfill 都旨在简化这一过程,但它们的设计哲学、兼容性策略和使用方式存在显著差异。本文从工程实践角度深入对比两者。

🧩 核心目标与设计理念

clipboard-copy 是一个极简工具函数,仅封装 navigator.clipboard.writeText(),不提供任何降级逻辑。它的假设是:你的目标环境已原生支持现代剪贴板 API(如 Chrome 66+、Firefox 63+、Safari 13.1+ 等)。

// clipboard-copy 使用示例
import copy from 'clipboard-copy';

try {
  await copy('要复制的文本');
  console.log('复制成功');
} catch (err) {
  console.error('复制失败', err);
}

clipboard-polyfill 则是一个完整的 polyfill 实现,不仅封装了 navigator.clipboard,还在不支持该 API 的旧浏览器中自动回退到 <textarea> + execCommand 的模拟方案,力求在尽可能多的环境中提供一致行为。

// clipboard-polyfill 使用示例
import { writeText } from 'clipboard-polyfill';

try {
  await writeText('要复制的文本');
  console.log('复制成功');
} catch (err) {
  console.error('复制失败', err);
}

注意:两者都返回 Promise,符合现代异步编程习惯。

🌐 浏览器兼容性策略:激进 vs 保守

这是两者最根本的分歧点。

clipboard-copy 采取“现代优先”策略。如果你在不支持 navigator.clipboard 的浏览器(如 IE11、旧版 Edge、Android WebView < 76)中调用它,会直接抛出异常。这意味着:

  • 你必须自行判断运行环境是否支持;
  • 或者你的产品已明确放弃对旧浏览器的支持。

clipboard-polyfill 则采用“最大兼容”策略。它内部检测 navigator.clipboard 是否可用,若不可用,则动态创建一个隐藏的 <textarea> 元素,聚焦后调用已被废弃但仍在多数旧浏览器中有效的 document.execCommand('copy')。这使得它能在 IE9+、旧版 Safari、Android 4.x 等环境中工作。

// clipboard-polyfill 内部大致逻辑(简化示意)
async function writeText(text) {
  if (navigator.clipboard) {
    return navigator.clipboard.writeText(text);
  }

  // 回退方案
  const textarea = document.createElement('textarea');
  textarea.value = text;
  textarea.style.position = 'fixed';
  textarea.style.opacity = '0';
  document.body.appendChild(textarea);
  textarea.select();
  const success = document.execCommand('copy');
  document.body.removeChild(textarea);
  if (!success) throw new Error('Copy command failed');
}

因此,如果你的应用仍需支持企业内网常见的 IE11 或老旧 Android 设备,clipboard-polyfill 是更稳妥的选择。

⚙️ API 设计与扩展能力

clipboard-copy 只暴露一个默认导出函数,功能单一:仅支持纯文本复制。不支持富文本(HTML)、自定义 MIME 类型或读取剪贴板内容。

// clipboard-copy 仅此一种用法
await copy('plain text only');

clipboard-polyfill 提供更丰富的 API:

  • writeText(text):复制纯文本(等价于 clipboard-copy 的功能);
  • write(blob):支持写入任意格式的数据(如 HTML 片段);
  • readText():从剪贴板读取文本(需用户手势触发且受权限控制)。
// clipboard-polyfill 支持富文本复制
import { write } from 'clipboard-polyfill';

const htmlBlob = new Blob(['<b>加粗文本</b>'], { type: 'text/html' });
const textBlob = new Blob(['加粗文本'], { type: 'text/plain' });
await write(new ClipboardItem({
  'text/html': htmlBlob,
  'text/plain': textBlob
}));

注意:富文本写入和读取在旧浏览器中无法通过 execCommand 模拟,因此这些高级功能在不支持 navigator.clipboard 的环境中会失效或抛错。

🔒 安全与权限模型

两者都遵循浏览器的安全限制:

  • 复制操作必须由用户手势(如点击)触发,否则会因缺少 TransientUserActivation 而被拒绝;
  • 在非安全上下文(HTTP 而非 HTTPS)中,部分浏览器会禁用 navigator.clipboard

clipboard-polyfill 在回退到 execCommand 时,虽然绕过了部分现代限制,但仍需用户交互(因为 execCommand('copy') 也要求焦点在可编辑元素上,而该元素的聚焦通常由点击事件触发)。因此,在安全模型上两者实际行为一致,只是底层实现不同。

📦 构建与 Tree-shaking

clipboard-copy 代码极其精简(仅几行),无任何依赖,天然支持 tree-shaking。即使你只导入一次,最终打包体积增量几乎可忽略。

clipboard-polyfill 为了支持多种回退路径和高级功能,代码量更大。但它采用模块化设计,如果你只使用 writeText,可通过 ES 模块导入避免引入 readTextwrite 的代码:

// 只导入 writeText,减少 bundle 体积
import { writeText } from 'clipboard-polyfill/write-text';

官方推荐这种按需导入方式,以平衡兼容性与体积。

🛠️ 错误处理与调试

当复制失败时,两者都会 reject Promise 并携带错误信息。

clipboard-copy 的错误通常是原生 DOMException,例如:

  • NotAllowedError:未由用户手势触发;
  • SecurityError:在非安全上下文中调用。

clipboard-polyfill 在回退路径中可能抛出自定义错误,例如:

  • Copy command returned falseexecCommand('copy') 返回 false,表示操作未成功(常见于某些移动端浏览器);
  • Cannot read property 'select' of null:DOM 操作异常。

建议在生产环境中统一捕获错误并提供用户友好的提示(如“请手动长按复制”)。

✅ 如何选择?关键决策因素

考量维度选择 clipboard-copy选择 clipboard-polyfill
目标浏览器仅现代浏览器(Chrome/Firefox/Safari 最新版)需支持 IE11、旧版移动浏览器等
功能需求仅需纯文本复制需要富文本、读取剪贴板等高级功能
包体积敏感度极致轻量(< 0.5KB)可接受稍大体积(按需导入可优化)
维护复杂度无兼容性负担需理解其回退机制及潜在边缘情况

💡 总结

  • 如果你的项目已完全拥抱现代 Web 标准,且无需考虑老旧环境,clipboard-copy 是最简洁、最直接的选择 —— 它不做多余的事,只做好一件事。
  • 如果你需要覆盖更广泛的用户设备,或未来可能需要富文本复制能力,clipboard-polyfill 提供了经过充分测试的兼容层和扩展 API,值得引入。

无论选择哪个,都应始终包裹在 try/catch 中,并为用户提供复制失败的备选方案(如显示可选中文本区域)。毕竟,剪贴板操作的成功与否,最终取决于用户设备和浏览器策略,而非你的代码。

如何选择: clipboard-copy vs clipboard-polyfill

  • clipboard-copy:

    选择 clipboard-copy 如果你的应用仅面向现代浏览器(如 Chrome 66+、Firefox 63+、Safari 13.1+),且只需要基本的纯文本复制功能。它代码极简、零依赖、体积微小,适合追求极致轻量且无需考虑老旧环境的项目。

  • clipboard-polyfill:

    选择 clipboard-polyfill 如果你需要支持 IE11、旧版移动浏览器等不支持 navigator.clipboard 的环境,或未来可能需要富文本复制、剪贴板读取等高级功能。它提供了经过验证的兼容层和模块化导入选项,适合对浏览器覆盖范围有更高要求的项目。

clipboard-copy的README

clipboard-copy travis npm downloads size javascript style guide

Lightweight copy to clipboard for the web

The goal of this package is to offer simple copy-to-clipboard functionality in modern web browsers using the fewest bytes. To do so, this package only supports modern browsers. No fallback using Adobe Flash, no hacks. Just 30 lines of code.

Unlike other implementations, text copied with clipboard-copy is clean and unstyled. Copied text will not inherit HTML/CSS styling like the page's background color.

Supported browsers: Chrome, Firefox, Edge, Safari.

Works in the browser with browserify!

install

npm install clipboard-copy

usage

const copy = require('clipboard-copy')

button.addEventListener('click', function () {
  copy('This is some cool text')
})

API

successPromise = copy(text)

Copy the given text to the user's clipboard. Returns successPromise, a promise that resolves if the copy was successful and rejects if the copy failed.

Note: in most browsers, copying to the clipboard is only allowed if copy() is triggered in direct response to a user gesture like a 'click' or a 'keypress'.

comparison to alternatives

testing

Testing this module is currently a manual process. Open test.html in your web browser and follow the short instructions. The web page will always load the latest version of the module, no bundling is necessary.

license

MIT. Copyright (c) Feross Aboukhadijeh.