乐趣区

关于javascript:异步clipboard-api

原文地址:https://webkit.org/blog/10855/async-clipboard-api/;
第一次翻译,盲目语句什么的也有些僵硬,可能存在不少问题,请大家不吝赐教,谢谢。

1. 根底性能

Safari13.1 减少对 async Clipboard API 的反对。该 api 容许 web 开发者在剪贴板中读写文字 / 图片数据,并且在剪贴板数据的读写中有很多优于以后的做法。

该 api 次要介绍了两个性能:

  • clipboard:通过 navigator.clipboard 应用,蕴含了一些从零碎剪贴板读写数据的办法;
  • clipboardItem:代表了剪贴板泛滥信息中的一项,目前 webkit 读写反对四种 MIME 类型:text/plain,text/html,text/uri-list 和 image/png;

    从概念上来说,clipboard 由一个或多个 clipboardItem 有序组成。每个 clipboardItem 可能会蕴含多种 MIME 类型,比如说复制多个 image 文件,个别会创立多个“image/png”类型的 clipboardItem,然而如果图文混合类型,个别会创立一个带有“image/png”和“text/plain”两种类型的 clipboardItem。

    能够应用 clipboard.read 去读取零碎剪切板中的数据,这个办法能够异步的获取到 clipboardItem 的数组汇合,数组中的每一项都蕴含了 MIME 类型到 blob 的映射。同样的,clipboard.write 能够将给定的 clipboardItem 数组写入零碎剪切板。但如果内容只是文本的话,应用 clipboard.readText 和 clipboard.writeText 更简略不便些。

    每个 clipboardItem 还有 presentationStyle 属性,该属性表明该项最好是内联数据还是“附件”(相似 file 的实体),能够用于辨别文本还是 HTML 文件。

2. 代码示例

写入文本数据:

<button id="new-copy">Copy text</button>

<script>

  document.getElementById("new-copy").addEventListener("click", event => {navigator.clipboard.writeText("This text was copied programmatically.");

  });

</script>

这比当初须要选中 text 内容而后再调用 execute 复制文本要简略很多。


写入 clipboardItem:

参数是一个 clipboardItem 数组,每一项 MIME 类型都是 promise,resolve 的内容能够被转为雷同类型的 string 或者 blob

<button id="copy-html">Copy text and markup</button>

<div>Then paste in the box below:</div>

<div contenteditable spellcheck="false" style="width: 200px; height: 100px; overflow: hidden; border: 1px solid black;"></div>

<script>

  document.getElementById("copy-html").addEventListener("click", event => {

    navigator.clipboard.write([

        new ClipboardItem({"text/plain": Promise.resolve("This text was copied using `Clipboard.prototype.write`."),

            "text/html": Promise.resolve("<p style='color: red; font-style: oblique;'>This text was copied using <code>Clipboard.prototype.write</code>.</p>"),

        }),

    ]);

  });

</script>

应用 dataTransfer api 来复制内容的时候,须要创立一个暗藏的文本域,在文本域上注册一个 copy 的事件,聚焦之后通过触发程序的复制在 dataTransfer 里设置数据,最初调用 preventDefault 办法。???

write 和 writeItem 都是异步的,如果在 pending 的时候从新写入,前一个会立刻返回 reject,而后写入新的内容。

在 IOS 和 macOS 零碎上,写入的程序也很重要。webkit 依照指定的程序写入,先写入的有“更高的保真度”,在 IOS 和 macOS 上的原生 app 能够以此为依据来抉择适当的 UTI(universal type identifier)来读取。

读取数据:

<span style="font-weight: bold; background-color: black; color: white;">Select this text and copy</span>

<div><button id="read-html">Paste HTML below</button></div>

<div id="html-output"></div>

<script>

document.getElementById("read-html").addEventListener("click", async clickEvent => {let items = await navigator.clipboard.read();

    for (let item of items) {if (!item.types.includes("text/html"))

            continue;

        let reader = new FileReader;

        reader.addEventListener("load", loadEvent => {document.getElementById("html-output").innerHTML = reader.result;

        });

        reader.readAsText(await item.getType("text/html"));

        break;

    }

});

</script>

有几个点能够留神一下:

  • 和 write 一样,read 也是异步的,获取 clipboardItem 和转换 blob 都返回的是 promise
  • 读取数据时,类型会保留,写入的程序和读取的时候是一样的

3. 平安和隐衷

clipboard api 功能强大,能够从剪切板读取数据,所以读取时有很多安全策略,敏感数据,比方明码之类的,如果没有用户    明确的批准,是不被容许应用的。比如说复制了歹意的“text/html”信息,粘贴到另外的网页中,很有可能导致跨站脚本攻打。

以下是一些平安限度:

  • http 的网站是无奈应用该 api 的
  • 复制的申请必须在用户手势下触发,如果不是“click”,“touch”之类的用户手势,promise 会返回 reject
  • “text/html”和“image/png”在写入之前会脱敏,标记在 js 被禁用的独立文档中加载,而且只取页面的可见局部,比方 script 元素,正文内容,display:none 以及事件属性等都会被去除。对 png 图片来说,被首次解码后展现图像,在被写入粘贴板之前会被再次编码,这得确保网站图片不被损坏,如果图片无奈被解码,写入的 promise 会返回 reject。更多的脱敏信息能够在 Clipboard API Improvements 中找到。
  • 因为用户可能并没有意识到复制了敏感信息,所以读取粘贴内容的限度比写入的限度严格很多。如果页面希图在用户手势之外用编程形式读取粘贴板的内容,会立刻返回 reject。然而如果用户明确的触发了粘贴操作 (比方 macOS 的 command+ v 快捷键或者 IOS 的粘贴操作),WebKit 会容许程序执行粘贴操作。如果是同源拜访,剪切板会主动受权。如果上述条件都不合乎,WebKit 就会在用户持续粘贴操作的时候展现明确的 ui 面板让其操作。在 IOS 上,它的模式是有繁多选项的标注栏,在 macOS 上,是菜单选项。轻触或点击页面的任意一处(或者执行其余操作,比方切换 tab 或者暗藏 safari) 都会导致 promise 被 reject。只有用户在 ui 上明确触发了粘贴操作,页面才会受权容许操作执行。
  • 从剪贴板读取数据也要进行脱敏,防止用户在无心中裸露敏感数据,比方 image 数据会被剥离 EXIF 数据,其中蕴含了名字之类的信息。读取的标记信息也会被去掉正文之类的信息。

这些政策确保了异步 clipboard api 开发者没有滥用以及毁坏用户平安与隐衷的危险,还能取得良好的开发体验。

4. 将来的倒退

    咱们会持续欠缺这个 api,咱们会减少自定义类型的反对,也会反对更错的 MIME 类型,比方“image/jpeg”或者“image/svg+xml”,如果有 bug 欢送提供至 bugs.webkit.org

退出移动版