原文地址: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