【问题标题】:JS convert blob url to Base64 fileJS 将 blob url 转换为 Base64 文件
【发布时间】:2017-01-05 08:47:42
【问题描述】:

有如下代码:

console.log(blob);
var reader = new window.FileReader();
reader.onloadend = function() {            
  console.log(reader.result);
};
reader.readAsDataURL(blob);

blob 是“blob:http://localhost:3000/e3c23a22-75b1-4b83-b39a-75104d1909b9”,我收到以下错误:

TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.

如何修复此错误并将 Blob 转换为 Base64 编码图像?提前致谢!

【问题讨论】:

  • 嘿伙计,我遇到了同样的问题。您是否通过任何其他方式了解了 iDEA。
  • 关于这个问题的任何更新
  • 您的代码对我有用。谢谢

标签: javascript


【解决方案1】:

我知道这是一个老问题,但我最近遇到了这个问题,我花了一段时间来解决它。所以我会回答这个问题,以防有人再次遇到它。

首先,我认为变量blob 的命名非常混乱。 Blob URL 和 Blob 对象 是不同的东西。 This answer 很好地解释了 Blob URL 是什么。我认为您应该将其重命名如下。

var blobUrl = 'blob:http://localhost:3000/e3c2...'

那么,FileReader 的函数readAsDataURL 需要一个Blob 对象 作为其参数。你给它的是变量blob,它是一个Blob URL。

所以你需要做的是:

  1. 恢复用于创建 Blob URL 的 Blob 对象
  2. 使用readAsDataURL将恢复的Blob Object转换为base64 url​​

这是我在this answer 中找到的代码:

var blob = new Blob(["Hello, world!"], { type: 'text/plain' });
var blobUrl = URL.createObjectURL(blob);

var xhr = new XMLHttpRequest;
xhr.responseType = 'blob';

xhr.onload = function() {
   var recoveredBlob = xhr.response;

   var reader = new FileReader;

   reader.onload = function() {
     var blobAsDataUrl = reader.result;
     window.location = blobAsDataUrl;
   };

   reader.readAsDataURL(recoveredBlob);
};

xhr.open('GET', blobUrl);
xhr.send();

【讨论】:

    【解决方案2】:

    您需要从上传程序传入整个文件对象,而不仅仅是 blob url。整个文件对象是指名称、类型、url 等。

    基本上如果上传者在数组中有一个文件,即files[0],你会传入readAsDataURL(files[0])。

    【讨论】:

      【解决方案3】:

      只需使用 fetch api:

      const blob = await fetch(blobUrl).then(res => res.blob())
      

      【讨论】:

        【解决方案4】:

        孙浩然的回答太棒了,带领我朝着正确的方向更好地理解,并且像一个魅力一样工作。
        下面我将根据孙浩然的回答分享我在 Angular 11 中所做的事情。我需要实现的是在 Promise 内执行操作并在完成 TypeScript 时保持范围:

        private blobUrlToBase64(blobUrl: string): Promise<string> {
          return new Promise<string>((resolve, reject) => {
            const reader = new FileReader();
            const xhr = new XMLHttpRequest();
            xhr.responseType = 'blob';
        
            xhr.onload = function () {
              reader.readAsDataURL(xhr.response);
              reader.onloadend = function () { resolve(reader.result as string); }
              reader.onerror = function (ev) { reject(`Exception reading Blob > xhr.response: ${xhr.response}\nLast Progress Event: ${ev}`); };
            };
            xhr.onerror = function (ev) { reject(`Exception fetching Blob > BlobUrl: ${blobUrl}\nLast Progress Event: ${ev}`); };
        
            xhr.open('GET', blobUrl);
            xhr.send();
          });
        }
        

        【讨论】:

        • 一个javascript问题的答案应该用javascript来回答...
        • 是的,你是对的,孙浩然的回答适用于javascript。但是,正如我在回答中所说的“我需要实现的是在承诺范围内进行操作并在完成 TypeScript 时保持范围”。我这么说是有原因的,无尽的。互联网上的人们会为 JS 和 TS 提出这个问题,希望这两种解决方案都对他们有用。但严格来说,你是对的。
        【解决方案5】:

        这里没有关于 xhr 的代码,但可能是您没有正确设置 responseType。在xhr.send() 之前尝试xhr.responseType = 'blob'。

        此外,除了使用FileReader,以下可能更直接:

        xhr.onreadystatechange = function(){
            if (this.readyState == 4 && this.status == 200){
                var url = window.URL || window.webkitURL;
                img.src = url.createObjectURL(this.response);
            }
        }
        

        【讨论】:

        • 什么?那不是被问到的。他们显然在使用视频流之类的东西,并希望将 blob url 转换为 base64 以在其他地方使用。
        猜你喜欢
        • 2019-11-18
        • 1970-01-01
        • 2013-09-10
        • 1970-01-01
        • 2021-07-27
        • 2021-06-20
        • 1970-01-01
        • 2022-08-12
        • 1970-01-01
        相关资源
        最近更新 更多