来自 DataURL 的 Blob?

IT技术 javascript fileapi
2021-01-26 05:48:25

使用FileReader's readAsDataURL()I 可以将任意数据转换为数据 URL。有没有办法Blob使用内置浏览器 api将数据 URL 转换回实例?

6个回答

用户 Matt 在一年前提出了以下代码(How to convert dataURL to file object in javascript?)这可能对您有所帮助

编辑:正如一些评论者所报告的那样,BlobBuilder 一段时间前已被弃用。这是更新后的代码:

function dataURItoBlob(dataURI) {
  // convert base64 to raw binary data held in a string
  // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
  var byteString = atob(dataURI.split(',')[1]);

  // separate out the mime component
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

  // write the bytes of the string to an ArrayBuffer
  var ab = new ArrayBuffer(byteString.length);

  // create a view into the buffer
  var ia = new Uint8Array(ab);

  // set the bytes of the buffer to the correct values
  for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
  }

  // write the ArrayBuffer to a blob, and you're done
  var blob = new Blob([ab], {type: mimeString});
  return blob;

}
重复的拆分似乎有点浪费,因为这可能是一个非常大的字符串。
2021-03-20 05:48:25
变量“ia”的作用是什么 - 它分配了一个值,但从未用于形成 blob。为什么?
2021-03-27 05:48:25
@BT:我猜stackoverflow.com/a/30407840/271577(注意重定向的 URL 包括“#6850276”)。
2021-04-06 05:48:25
我如何找到 SO 答案#6850276?
2021-04-08 05:48:25
Blaze, Ward:ia 是缓冲区视图因此,当您在 ia 中设置每个字节时,它正在写入缓冲区。如果没有 ia 循环,缓冲区将完全为空。
2021-04-10 05:48:25

像@Adria 方法,但使用 Fetch api 并且更小 [ caniuse? ]
不必考虑 mimetype,因为 blob 响应类型是开箱即用的

警告:可能违反内容安全政策 (CSP)
...如果你使用那些东西

var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="

fetch(url)
.then(res => res.blob())
.then(blob => console.log(blob))

不要认为你可以在不使用 lib 的情况下做得更小

edge 14 和 safari 10.1 支持
2021-03-13 05:48:25
更大的问题fetch是它强制使用异步 API。
2021-03-16 05:48:25
效果很好,但是从服务器读取时文件没有扩展名。有什么想法吗?
2021-03-31 05:48:25
异步版本: const blob = await (await fetch(url)).blob();
2021-04-10 05:48:25
十分优雅。不幸的是,edge 13 和 safari 不支持“获取”。
2021-04-11 05:48:25

现代浏览器中,可以使用 Christian d'Heureuse 在评论中建议的 one liner:

const blob = await (await fetch(dataURI)).blob(); 
这种方法的一个警告是,如果您的应用程序有任何内容安全策略 (CSP),这可能会违反您的内容安全策略 (CSP)。
2021-03-16 05:48:25
dataURItoBlob : function(dataURI, dataTYPE) {
        var binary = atob(dataURI.split(',')[1]), array = [];
        for(var i = 0; i < binary.length; i++) array.push(binary.charCodeAt(i));
        return new Blob([new Uint8Array(array)], {type: dataTYPE});
    }

输入 dataURI 是数据 URL 和 dataTYPE 是文件类型,然后输出 blob 对象

dataTYPE嵌入dataURI,因此应被解析为第一个答案。
2021-03-19 05:48:25
dataURL2Blob 来自我的图像处理插件,您可以查看此链接。我只是复制我自己的代码。github.com/xenophon566/html5.upload/blob/master/js/...
2021-03-29 05:48:25

基于 XHR 的方法。

function dataURLtoBlob( dataUrl, callback )
{
    var req = new XMLHttpRequest;

    req.open( 'GET', dataUrl );
    req.responseType = 'arraybuffer'; // Can't use blob directly because of https://crbug.com/412752

    req.onload = function fileLoaded(e)
    {
        // If you require the blob to have correct mime type
        var mime = this.getResponseHeader('content-type');

        callback( new Blob([this.response], {type:mime}) );
    };

    req.send();
}

dataURLtoBlob( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', function( blob )
{
    console.log( blob );
});
看来,这是现在最好的办法了。谢谢!
2021-04-01 05:48:25
问题是来自 DataURL 的 Blob?
2021-04-02 05:48:25
在 Safari 中不起作用 - 如果从 HTTPS 加载页面,它将引发跨域错误。
2021-04-11 05:48:25