本文翻译自:Creating a Blob from a base64 string in JavaScript

I have base64-encoded binary data in a string. 我在一个字符串中有base64编码的二进制数据。

const contentType = 'image/png';
const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';

I would like to create a blob: URL containing this data and display it to the user. 我想创建一个blob:包含此数据的URL并将其显示给用户。

const blob = new Blob(????, {type: contentType});
const blobUrl = URL.createObjectURL(blob);window.location = blobUrl;

I haven't been been able to figure out how to create the Blob . 我一直无法弄清楚如何创建Blob

In some cases I am able to avoid this by using a data: URL instead. 在某些情况下,我可以使用data: URL来避免这种情况。

const dataUrl = `data:${contentType};base64,${b64Data}`;window.location = dataUrl;

However in most cases the data: URLs are prohibitively large. 但是,在大多数情况下, data: URL太大了。


How can I decode a base64 string to a Blob object in JavaScript? 如何在JavaScript中将base64字符串解码为Blob对象?


#1楼

参考:https://stackoom.com/question/16AGV/在JavaScript中从base-字符串创建Blob


#2楼

The atob function will decode a base64-encoded string into a new string with a character for each byte of the binary data. atob函数会将base64编码的字符串解码为一个新的字符串,并为二进制数据的每个字节添加一个字符。

const byteCharacters = atob(b64Data);

Each character's code point (charCode) will be the value of the byte. 每个字符的代码点(charCode)将是字节的值。 We can create an array of byte values by applying this using the .charCodeAt method for each character in the string. 我们可以使用.charCodeAt方法为字符串中的每个字符应用字节值数组。

const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {byteNumbers[i] = byteCharacters.charCodeAt(i);
}

You can convert this array of byte values into a real typed byte array by passing it to the Uint8Array constructor. 您可以将该字节值数组传递给Uint8Array构造函数,以将其转换为实型字节数组。

const byteArray = new Uint8Array(byteNumbers);

This in turn can be converted to a Blob by wrapping it in an array and passing it to the Blob constructor. 这又可以被转换成一个Blob通过在阵列中包裹它,并将其传递到Blob构造。

const blob = new Blob([byteArray], {type: contentType});

The code above works. 上面的代码有效。 However the performance can be improved a little by processing the byteCharacters in smaller slices, rather than all at once. 但是,通过在较小的片中而不是一次全部处理byteCharacters可以稍微提高性能。 In my rough testing 512 bytes seems to be a good slice size. 在我的粗略测试中,512字节似乎是一个不错的切片大小。 This gives us the following function. 这为我们提供了以下功能。

const b64toBlob = (b64Data, contentType='', sliceSize=512) => {const byteCharacters = atob(b64Data);const byteArrays = [];for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {const slice = byteCharacters.slice(offset, offset + sliceSize);const byteNumbers = new Array(slice.length);for (let i = 0; i < slice.length; i++) {byteNumbers[i] = slice.charCodeAt(i);}const byteArray = new Uint8Array(byteNumbers);byteArrays.push(byteArray);}const blob = new Blob(byteArrays, {type: contentType});return blob;
}
const blob = b64toBlob(b64Data, contentType);
const blobUrl = URL.createObjectURL(blob);window.location = blobUrl;

Full Example: 完整示例:

 const b64toBlob = (b64Data, contentType='', sliceSize=512) => { const byteCharacters = atob(b64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { const slice = byteCharacters.slice(offset, offset + sliceSize); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } const blob = new Blob(byteArrays, {type: contentType}); return blob; } const contentType = 'image/png'; const b64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='; const blob = b64toBlob(b64Data, contentType); const blobUrl = URL.createObjectURL(blob); const img = document.createElement('img'); img.src = blobUrl; document.body.appendChild(img); 

#3楼

Optimized (but less readable) implementation: 优化(但可读性较差)的实现:

function base64toBlob(base64Data, contentType) {contentType = contentType || '';var sliceSize = 1024;var byteCharacters = atob(base64Data);var bytesLength = byteCharacters.length;var slicesCount = Math.ceil(bytesLength / sliceSize);var byteArrays = new Array(slicesCount);for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {var begin = sliceIndex * sliceSize;var end = Math.min(begin + sliceSize, bytesLength);var bytes = new Array(end - begin);for (var offset = begin, i = 0; offset < end; ++i, ++offset) {bytes[i] = byteCharacters[offset].charCodeAt(0);}byteArrays[sliceIndex] = new Uint8Array(bytes);}return new Blob(byteArrays, { type: contentType });
}

#4楼

For image data, I find it simpler to use canvas.toBlob (asynchronous) 对于图像数据,我发现使用canvas.toBlob (异步)更为简单

function b64toBlob(b64, onsuccess, onerror) {var img = new Image();img.onerror = onerror;img.onload = function onload() {var canvas = document.createElement('canvas');canvas.width = img.width;canvas.height = img.height;var ctx = canvas.getContext('2d');ctx.drawImage(img, 0, 0, canvas.width, canvas.height);canvas.toBlob(onsuccess);};img.src = b64;
}var base64Data = 'data:image/jpg;base64,/9j/4AAQSkZJRgABAQA...';
b64toBlob(base64Data,function(blob) {var url = window.URL.createObjectURL(blob);// do something with url}, function(error) {// handle error});

#5楼

For all browser support, especially on android. 对于所有浏览器支持,尤其是在android上。 Perhaps you can add this 也许你可以添加这个

   try{blob = new Blob( byteArrays, {type : contentType});}catch(e){// TypeError old chrome and FFwindow.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;if(e.name == 'TypeError' && window.BlobBuilder){var bb = new BlobBuilder();bb.append(byteArrays);blob = bb.getBlob(contentType);}else if(e.name == "InvalidStateError"){// InvalidStateError (tested on FF13 WinXP)blob = new Blob(byteArrays, {type : contentType});}else{// We're screwed, blob constructor unsupported entirely   }}

#6楼

I noticed, that Internet Explorer 11 gets incredibly slow when slicing the data like jeremy suggested. 我注意到,像jeremy建议的那样对数据进行切片时,Internet Explorer 11的速度变得异常慢。 This is true for Chrome, but IE seems to have a problem when passing the sliced data to the Blob-Constructor. 对于Chrome来说确实如此,但是将切片的数据传递给Blob构造函数时,IE似乎存在问题。 On my machine, passing 5 MB of data makes IE crash and memory consumption is going through the roof. 在我的机器上,传递5 MB的数据会使IE崩溃,并且内存消耗正在迅速增加。 Chrome creates the blob in no time. Chrome会立即创建Blob。

Run this code for a comparism: 运行以下代码进行比较:

var byteArrays = [],megaBytes = 2,byteArray = new Uint8Array(megaBytes*1024*1024),block,blobSlowOnIE, blobFastOnIE,i;for (i = 0; i < (megaBytes*1024); i++) {block = new Uint8Array(1024);byteArrays.push(block);
}//debugger;console.profile("No Slices");
blobSlowOnIE = new Blob(byteArrays,  { type: 'text/plain' });
console.profileEnd();console.profile("Slices");
blobFastOnIE = new Blob([byteArray],  { type: 'text/plain' });
console.profileEnd();

So I decided to include both methods described by jeremy in one function. 因此,我决定将jeremy描述的两种方法都包含在一个函数中。 Credits go to him for this. 这归功于他。

function base64toBlob(base64Data, contentType, sliceSize) {var byteCharacters,byteArray,byteNumbers,blobData,blob;contentType = contentType || '';byteCharacters = atob(base64Data);// Get blob data sliced or notblobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();blob = new Blob(blobData, { type: contentType });return blob;/** Get blob data in one slice.* => Fast in IE on new Blob(...)*/function getBlobDataAtOnce() {byteNumbers = new Array(byteCharacters.length);for (var i = 0; i < byteCharacters.length; i++) {byteNumbers[i] = byteCharacters.charCodeAt(i);}byteArray = new Uint8Array(byteNumbers);return [byteArray];}/** Get blob data in multiple slices.* => Slow in IE on new Blob(...)*/function getBlobDataSliced() {var slice,byteArrays = [];for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {slice = byteCharacters.slice(offset, offset + sliceSize);byteNumbers = new Array(slice.length);for (var i = 0; i < slice.length; i++) {byteNumbers[i] = slice.charCodeAt(i);}byteArray = new Uint8Array(byteNumbers);// Add slicebyteArrays.push(byteArray);}return byteArrays;}
}

在JavaScript中从base64字符串创建Blob相关推荐

  1. java两字符串是否相等_Java与JavaScript中判断两字符串是否相等的区别

    JavaScript是一种常用的脚本语言,这也决定了其相对于其他编程语言显得并不是很规范.在JavaScript中判断两字符串是否相等 直接用==,这与C++里的String类一样.而Java里的等号 ...

  2. 在JavaScript中解析查询字符串[重复]

    本文翻译自:Parse query string in JavaScript [duplicate] Possible Duplicate: 可能重复: How can I get query str ...

  3. java中字符串和数组如何比较_[Java教程]javascript中数组和字符串的方法比较

    [Java教程]javascript中数组和字符串的方法比较 0 2016-07-19 23:00:05 ×目录[1]可索引 [2]转换 [3]拼接[4]创建[5]位置 前面的话 字符串和数组有很多的 ...

  4. javascript中的Base64.UTF8编码与解码详解

    javascript中的Base64.UTF8编码与解码详解 本文给大家介绍的是javascript中的Base64.UTF8编码与解码的函数源码分享以及使用范例,十分实用,推荐给小伙伴们,希望大家能 ...

  5. JavaScript中常见的字符串操作函数及用法汇总

    转载地址:http://www.jb51.net/article/65358.htm 这篇文章主要介绍了JavaScript中常见的字符串操作函数及用法,实例汇总了javascript常见的字符串转换 ...

  6. JavaScript:实现将 base64 字符串转换为字节数组算法(附完整源码)

    JavaScript:实现将 base64 字符串转换为字节数组算法 function base64ToBuffer (b64) {// The base64 encoding uses the fo ...

  7. Javascript 中的长字符串拼接

    字符串拼接是所有程序设计语言都需要的操作.当拼接结果较长时,如何保证效率就成为一个很重要的问题.C 语言的 strcat 函数直接操作内存,效率自然最高:C++ 的 string 类是可变的,本质上也 ...

  8. lastindexof php,javascript 中查找指定字符串indexOf(),lastIndexOf(),match()

    在javascript中,有以下三个方法均可实现在字符串中查找指定的字符及字符串. str.indexOf(); 此方法:查找字符在字符串对象中第一次出现的位置.存在,则返回字符串所在的位置.不存在, ...

  9. JavaScript中的面向对象--对象创建

    JavaScript高级程序设计第3版总结p156 1.JavaScript中的对象 首先,ECMAScript 中函数实际上是对象.每个函数都是 Function 类型的实例,而且都与其他引用类型一 ...

最新文章

  1. CentOS 7 命令
  2. 供销大集有潜力吗_菌肥内幕被揭开!快看你买的靠谱吗?
  3. Weblogic下创建JMS消息服务
  4. 电脑工具栏怎么调整到下面_雷电模拟器4.0怎么玩召唤与合成 一键下载轻松游玩 - 工具软件...
  5. LeetCode 2023. 连接后等于目标字符串的字符串对
  6. 清华开学,713分寒门学霸揭露一个真相:别抱怨读书苦,那是你看世界的路
  7. js简易计算机代码if语句,简单学习下JS里的if语句的写法
  8. 新垣结衣AI换脸郭德纲 网友:换脸史上最惨的车祸现场
  9. matlab 引号内变量,MATLAB 7.0 单引号内变量现实问题!
  10. Windows 必知命令
  11. java 人脸识别 性别识别
  12. ShipConstructor.2006v1.00.rar
  13. 使用ENVI对遥感图像进行图像镶嵌、图像裁剪。
  14. UML统一建模语言第3章 UML建模工具简介课后习题
  15. Glide 的 transformation
  16. 【谷歌浏览器打不开Axure解决办法~】
  17. [小技巧] git: Your branch and 'origin/master' have diverged
  18. 2020 dns排名_2020年最快的dns是多少_动漫台
  19. CF513C Maximum Subrectangle
  20. 基于Quartz.net 的任务调度平台Weiz.TaskManager

热门文章

  1. Oracle 取某100天的每一天的日期
  2. Python 网页爬虫 文本处理 科学计算 机器学习 数据挖掘兵器谱 - 数客
  3. LinkedHashMap/HashMap 介绍
  4. Java 非小数BigDecimal转换为Integer
  5. 6.Python学习笔记:[enumerate元素加序号;isdigit()像数字;len()计算长度]
  6. spring 4.0下集成webservice
  7. servlet路径跳转
  8. js 的函数参数的默认值问题
  9. SQLserver2012 修改数据库架构
  10. 怀旧系列(5)----大学时代的疯狂