226

这是我想要对Blob字符串Base64执行的代码片段:

此注释部分有效,并且当由此生成的 URL 设置为 img src 时,它会显示图像:

var blob = items[i].getAsFile();
//var URLObj = window.URL || window.webkitURL;
//var source = URLObj.createObjectURL(blob);
//console.log("image source=" + source);

var reader = new FileReader();
reader.onload = function(event){
console.log(event.target.result)
}; // data url!
var source = reader.readAsBinaryString(blob);

问题在于较低的代码,生成的源变量为空

更新:

有没有更简单的方法可以使用 JQuery 从 Blob 文件创建 Base64 字符串,如上面的代码所示?

4

12 回答 12

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

文档 readAsDataURL编码为 base64

作为一项await功能:

function blobToBase64(blob) {
  return new Promise((resolve, _) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}

注意:如果不首先删除 Base64 编码数据之前的 Data-URL 声明,则无法将 blob 的结果直接解码为 Base64。要仅检索 Base64 编码的字符串,请首先从结果中删除 data: / ;base64。

于 2013-09-06T05:05:00.900 回答
45

这对我有用:

var blobToBase64 = function(blob, callback) {
    var reader = new FileReader();
    reader.onload = function() {
        var dataUrl = reader.result;
        var base64 = dataUrl.split(',')[1];
        callback(base64);
    };
    reader.readAsDataURL(blob);
};
于 2016-10-27T16:19:07.367 回答
31

有一种不依赖于任何堆栈的纯 JavaSript 方式:

const blobToBase64 = blob => {
  const reader = new FileReader();
  reader.readAsDataURL(blob);
  return new Promise(resolve => {
    reader.onloadend = () => {
      resolve(reader.result);
    };
  });
};

要使用此辅助函数,您应该设置一个回调,例如:

blobToBase64(blobData).then(res => {
  // do what you wanna do
  console.log(res); // res is base64 now
});

我为我在 React Native 项目上的问题编写了这个辅助函数,我想下载一个图像,然后将其存储为缓存图像:

fetch(imageAddressAsStringValue)
  .then(res => res.blob())
  .then(blobToBase64)
  .then(finalResult => { 
    storeOnMyLocalDatabase(finalResult);
  });
于 2020-04-15T10:06:27.733 回答
8
var audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;

var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
     base64data = reader.result;
     console.log(base64data);
}
于 2017-02-02T15:16:36.120 回答
6
function bufferToBinaryString(arrayBuffer){
    return String.fromCharCode(...new Uint8Array(arrayBuffer));
}
(async () => console.log(btoa(bufferToBinaryString(await new Response(blob).arrayBuffer()))))();

或者

function bufferToBinaryString(arrayBuffer){
    return String.fromCharCode(...new Uint8Array(arrayBuffer));
}
new Response(blob).arrayBuffer().then(arr_buf => console.log(btoa(bufferToBinaryString(arr_buf)))))

参见Response 的构造函数,你可以[blob, buffer source form data, readable stream, etc.]变成Response,然后可以[json, text, array buffer, blob]通过异步方法/回调将其变成。

编辑:正如@Ralph 提到的,将所有内容都转换为 utf-8 字符串会导致问题(不幸的是,响应 API 没有提供转换为二进制字符串的方法),因此数组缓冲区用作中间体,这需要另外两个步骤(将其转换为字节数组 THEN 到二进制字符串),如果你坚持使用本机btoa方法。

于 2019-05-20T09:30:53.323 回答
6

所以问题是你想上传一个 base 64 图像并且你有一个 blob url。现在适用于所有 html 5 浏览器的答案是:做:

  var fileInput = document.getElementById('myFileInputTag');
  var preview = document.getElementById('myImgTag');

  fileInput.addEventListener('change', function (e) {
      var url = URL.createObjectURL(e.target.files[0]);
      preview.setAttribute('src', url);
  });
function Upload()
{
     // preview can be image object or image element
     var myCanvas = document.getElementById('MyCanvas');
     var ctx = myCanvas.getContext('2d');
     ctx.drawImage(preview, 0,0);
     var base64Str = myCanvas.toDataURL();
     $.ajax({
         url: '/PathToServer',
         method: 'POST',
         data: {
             imageString: base64Str
         },
     success: function(data) { if(data && data.Success) {}},
     error: function(a,b,c){alert(c);}
     });
 }
于 2017-02-04T08:50:41.080 回答
4

另一种方法是在FileReader返回时使用一个简单的包装器Observable(片段位于TypeScript):

  function toBase64(blob: Blob): Observable<string> {
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    return fromEvent(reader, 'load')
      .pipe(map(() => (reader.result as string).split(',')[1]));
  }

用法:

toBase64(blob).subscribe(base64 => console.log(base64));
于 2020-12-06T11:27:28.503 回答
4

您可以通过以下方式解决问题:

var canvas = $('#canvas'); 
var b64Text = canvas.toDataURL();
b64Text = b64Text.replace('data&colon;image/png;base64,','');
var base64Data = b64Text;

我希望这对你有帮助

于 2016-12-15T12:36:37.303 回答
4
async function blobToBase64(blob) {
  return new Promise((resolve, _) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}

let blob = null; // <= your blob object goes here

blobToBase64(blob)
  .then(base64String => console.log(base64String));

也可以看看:

于 2021-02-11T16:51:22.313 回答
1

打字稿版本:

const blob2Base64 = (blob:Blob):Promise<string> => {
      return new Promise<string> ((resolve,reject)=> {
           const reader = new FileReader();
           reader.readAsDataURL(blob);
           reader.onload = () => resolve(reader.result.toString());
           reader.onerror = error => reject(error);
       })
      }

用法:

blob2Base64(blob).then(res=>console.log(res))
于 2021-06-21T16:57:28.153 回答
0

我想要一些我可以访问 base64 值的东西来存储到一个列表中,并且对我来说添加事件监听器是可行的。您只需要读取图像 blob 并在结果中返回 base64 的 FileReader。

createImageFromBlob(image: Blob) {
    const reader = new FileReader();
    const supportedImages = []; // you can also refer to some global variable
    reader.addEventListener(
      'load',
      () => {
        // reader.result will have the required base64 image
        const base64data = reader.result;
        supportedImages.push(base64data); // this can be a reference to global variable and store the value into that global list so as to use it in the other part
      },
      false
    );
    // The readAsDataURL method is used to read the contents of the specified Blob or File.
    if (image) {
      reader.readAsDataURL(image);
    }
 }

最后一部分是 readAsDataURL,它非常重要,用于读取指定 Blob 的内容

于 2020-07-31T05:21:18.470 回答
-1

异步 TypeScript 变体:

async function blobToBase64Async(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.onerror = (e) => reject(fileReader.error);
    fileReader.onloadend = (e) => {
      const dataUrl = fileReader.result as string;
      // remove "data:mime/type;base64," prefix from data url
      const base64 = dataUrl.substring(dataUrl.indexOf(',') + 1);
      resolve(base64);
    };
    fileReader.readAsDataURL(blob);
  });
}

示例用法:

async function fetchToBase64Async(url: string, init?: RequestInit): Promise<string> {
  try {
    const response = await fetch(url, init);
    if (!response.ok) {
      const responseText = await response.text();
      throw new Error("server status: " + response.status + "\n" + "server response:" + "\n" + responseText);
    }
    const blob = await response.blob();
    const base64 = await blobToBase64Async(blob);
    return base64;
  } catch (e) {
    throw new Error("failed to fetch: " + url + "\n" + "caused by: " + e);
  }
}

async function demoUsage() {
  const base64 = await fetchToBase64Async("https://httpstat.us/200", {
    method: "POST",
    headers: {
      "Accept": "*/*",
      "Authorization": "Bearer ...",
    }
  });
  console.log(base64);
}

笔记:

  • 我不明白为什么有些答案使用 theload而不是loadend事件
  • 我不明白为什么readAsDataURL在设置事件处理程序之前会调用一些答案
于 2021-06-04T14:05:21.497 回答