Async Clipboard API 的 Clipboard
接口可对系统剪贴板的内容提供读写权限。这样,Web 应用就可以实现剪切、复制和粘贴功能。您可以通过调用 read()
方法将剪贴板中的数据粘贴到应用中,也可以通过调用 write()
方法将数据复制到剪贴板中。除了文本、Portable Network Graphics (PNG) 格式的图片、经过净化和未经净化的 HTML 以及网站自定义格式之外,Async Clipboard API 现在还支持复制和粘贴 SVG 图片,这意味着您终于可以通过以图片(而非文本)的形式复制和粘贴 SVG 图片,或使用不太可靠的解决方法,更自然地与处理 SVG 的图片编辑软件互动。
地图项检测 SVG 支持
通过调用静态 ClipboardItem.supports()
方法并向其传递所需的 MIME 类型,检测对 SVG 图片(以及任何其他 MIME 类型)的支持。
const supportsSVG = () => {
if (
!('supports' in window.ClipboardItem) ||
!window.ClipboardItem.supports('image/svg+xml')
) {
return false;
}
return true;
};
复制 SVG 图片
通过使用对象填充 ClipboardItem
来复制 SVG 图片。包含 SVG 图片数据的 BLOB 是值,BLOB 的类型(在本例中为 'image/svg+xml'
)是键。
copyButton.addEventListener('click', async () => {
if (!supportsSVG()) {
return;
}
try {
const blob = await fetch(img.src).then((response) => response.blob());
await navigator.clipboard.write([
new window.ClipboardItem({
[blob.type]: blob,
}),
]);
} catch (err) {
console.error(err.name, err.message);
alert(err.message);
}
});
粘贴 SVG 图片
如需粘贴 SVG 图片,请从剪贴板中读取 ClipboardItem
,然后使用 getType()
方法获取所需类型(在本例中为 'image/svg+xml'
)。这会返回一个 blob,转换为 blob 网址后,您可以将其分配给 <img>
的 src
属性。
pasteButton.addEventListener('click', async () => {
if (!supportsSVG()) {
return;
}
const [clipboardItem] = await navigator.clipboard.read();
const svgBlob = await clipboardItem.getType('image/svg+xml');
if (!svgBlob) {
alert('No SVG in the clipboard.');
return;
}
const image = document.createElement('img');
const blobURL = URL.createObjectURL(svgBlob);
image.addEventListener('load', () => {
URL.revokeObjectURL(blobURL);
});
image.src = blobURL;
});
排错
SVG 是一种功能强大的格式,例如,它支持内嵌脚本。如果用户粘贴来自未知来源的内容,这可能会很危险,因此浏览器会运行一个净化步骤。复制数据时,Async Clipboard API 会生成格式正确的 SVG 文档,然后将其写入剪贴板。粘贴数据时,fragment 解析器会生成经过严格处理的 SVG fragment。因此,在粘贴操作之前,onclick
事件处理脚本属性仍然存在,但在粘贴后,这些属性会被移除。
演示
在 Glitch 上的演示中探索如何复制和粘贴 SVG。查看源代码,了解其工作原理。请务必在复制和粘贴之前和之后尝试点击任意圆圈。粘贴后,系统会移除可能存在危险性的 onclick
事件处理程序属性。
相关链接
- 使用此功能的正式版软件:
- ChromeStatus 条目
- 发货意图
- Chromium bug
- WebKit 标准位置
- Mozilla 标准位置
致谢
Microsoft Edge 团队实现了对 Chromium 中 Async Clipboard API 的 SVG 支持。此博文由 Rachel Andrew 和 Anupam Snigdha 审核。