现代浏览器推荐用 navigator.clipboard.writeText() 复制文本,需 HTTPS/localhost 安全上下文且由用户手势触发;老浏览器 fallback 到 document.execCommand('copy');复制 HTML 需 write() 和 ClipboardItem;注意权限提示与移动端兼容性。
navigator.clipboard.writeText() 最直接现代浏览器基本都支持这个 API,调用一次就能把字符串写进系统剪贴板,不用依赖 Flash 或隐藏 textarea。但要注意它只能在安全上下文(HTTPS 或 localhost)中运行,HTTP 站点会直接报错 SecurityError。
实操建议:
click 事件),不能在页面加载后自动执行,否则 Chrome/Firefox 会拒绝调用.catch() 触发button.addEventListener('click', async () => { try { await navigator.clipboard.writeText('要复制的文本'); } catch (err) { console.error('复制失败:', err); }});
document.execCommand('copy')
IE11、Safari 12 以下、部分旧版安卓 WebView 不支持 navigator.clipboard,这时候得退回到基于 textarea 的方案。核心是动态创建一个 textarea,设为可编辑、聚焦、选中内容,再执行 execCommand('copy')。
容易踩的坑:
立即学习“前端免费学习笔记(深入)”;
textarea 必须插入 DOM 且可见(不能 display: none 或 visibility: hidden),否则 Safari 和某些 Android 浏览器会静默失败select() 或 setSelectionRange(),仅设置 value 不够execCommand 已被标记为废弃,Chrome 90+ 在非用户手势下会警告,但目前仍能用navigator.clipboard.write()
如果想复制带样式的 HTML 片段(比如一段加粗文字或表格),writeText() 不行,得用更底层的 write(),传入 ClipboardItem 数组。它支持多种 MIME 类型,包括 text/html 和 text/plain。
注意事项:
text/html(Firefox 目前只支持 text/plain)write(),只能降级为纯文本<html> 或 <body> 根标签)const htmlBlob = new Blob(['<strong>加粗文本</strong>'], {type: 'text/html'});const plainBlob = new Blob(['加粗文本'], {type: 'text/plain'});await navigator.clipboard.write([ new ClipboardItem({ 'text/html': htmlBlob, 'text/plain': plainBlob })]);
Chrome 和 Edge 在首次调用 navigator.clipboard 时会弹出权限请求浮层,用户点“拒绝”后,后续调用会直接失败,且不会再次提示。所以不能假设每次都能成功。
实用做法:
navigator.permissions.query() 返回 prompt 并不等于用户点了允许)navigator.clipboard 可能完全不可用,必须提前检测并准备备用路径。