Javascript 将Blob同步转换为二进制字符串

Javascript 将Blob同步转换为二进制字符串,javascript,filereader,synchronous,Javascript,Filereader,Synchronous,当用户复制画布选择时,我尝试将图像放入剪贴板: 所以我认为正确的方法应该是将canvas-tu-dataURL、dataURL转换为blob、blob转换为二进制字符串 从理论上讲,应该可以跳过这个斑点,但我不知道为什么 这就是我所做的: function copy(event) { console.log("copy"); console.log(event); //Get DataTransfer object var items = (event.c

当用户复制画布选择时,我尝试将图像放入剪贴板:

所以我认为正确的方法应该是将canvas-tu-dataURL、dataURL转换为blob、blob转换为二进制字符串

从理论上讲,应该可以跳过这个斑点,但我不知道为什么

这就是我所做的:

  function copy(event) {
    console.log("copy");
    console.log(event);

    //Get DataTransfer object
    var items = (event.clipboardData || event.originalEvent.clipboardData);
    //Canvas to blob
    var blob = Blob.fromDataURL(_this.editor.selection.getSelectedImage().toDataURL("image/png"));
    //File reader to convert blob to binary string
    var reader = new FileReader();
    //File reader is for some reason asynchronous
    reader.onloadend = function () {
      items.setData(reader.result, "image/png");
    }
    //This starts the conversion
    reader.readAsBinaryString(blob);

    //Prevent default copy operation
    event.preventDefault();
    event.cancelBubble = true;
    return false;
  }
  div.addEventListener('copy', copy);
但是当
DataTransfer
对象在
paste
事件线程之外使用时,
setData
不再有任何生效的机会


如何在同一个函数线程中进行转换?

这里有一个简单的方法,可以让您从一个blob同步到它的字节。我不确定这对任何二进制数据的效果如何

function blobToUint8Array(b) {
    var uri = URL.createObjectURL(b),
        xhr = new XMLHttpRequest(),
        i,
        ui8;

    xhr.open('GET', uri, false);
    xhr.send();

    URL.revokeObjectURL(uri);

    ui8 = new Uint8Array(xhr.response.length);

    for (i = 0; i < xhr.response.length; ++i) {
        ui8[i] = xhr.response.charCodeAt(i);
    }

    return ui8;
}

var b = new Blob(['abc'], {type: 'application/octet-stream'});
blobToUint8Array(b); // [97, 98, 99]
函数blobToUint8Array(b){
var uri=URL.createObjectURL(b),
xhr=新的XMLHttpRequest(),
我
ui8;
xhr.open('GET',uri,false);
xhr.send();
revokeObjectURL(uri);
ui8=新的Uint8Array(xhr.response.length);
对于(i=0;i

你应该考虑把它保持在同一个阶段,但是使它成为两个阶段,因为你可能最终锁定了浏览器。


此外,通过包含二进制安全的Base64解码器,您可以完全跳过Blob,并且可能不需要通过Base64和Blob,只需其中一个。通过将Blob获取为d,然后应用,Blob可以转换为二进制字符串。但是,这同样[需要
FileReader][3]
。在我的情况下,最好一起跳过blob:

//Canvas to binary
var data = atob(
  _this.editor.selection.getSelectedImage()  //Canvas
  .toDataURL("image/png")                    //Base64 URI
  .split(',')[1]                             //Base64 code
);

我想我将跳过blob阶段。不过我很好奇-为什么伪xhr是同步的?@TomášZato将
false
作为
open
方法的第三个参数传递。这不是最佳实践。对我来说,这是一个聪明的解决方案。但同步XMLHttpRequest只接受DOMString作为响应。这意味着,只要传输的字节数组与UTF8不兼容,高于127的字节就会被伪造
@Codesmith Yep,如果你只需要瞄准IE10或更高版本,那么这个选项也是有效的。setData中的参数顺序应该颠倒->items.setData(“image/png”,reader.result)我必须承认,我真的很难将画布放入剪贴簿数据对象并粘贴到MS Outlook消息或其他地方。托马斯,你能概述一下你将画布复制到剪贴板的最终解决方案吗。我已经尝试了几乎所有可以使用setData(“image/png”…)或items.field.add(file)等的方法。。要传递给setData的值应该是什么(“图像/url”,?)?谢谢。@belzebu除非有什么变化,否则我有坏消息。我在这个问题之后发布了一个问题,但仍然没有得到回答,因为这根本不可能: