blob转base64位 base64位转blob

本文介绍如何在前端开发中实现 Data URL 与 Blob 的相互转换,包括使用 JavaScript 编写的 dataURLtoBlob 和 blobToDataURL 两个实用函数。通过这些函数可以方便地在网页应用中处理图片等二进制文件。
//**dataURL to blob**
    function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: mime });
    }


    //**blob to dataURL**
    function blobToDataURL(blob, callback) {
        var a = new FileReader();
        a.onload = function (e) { callback(e.target.result); }
        a.readAsDataURL(blob);
    }


    //test:
    //var blob = dataURLtoBlob('data:text/plain;base64,YWFhYWFhYQ==');
    //blobToDataURL(blob, function (dataurl) {
    //    console.log(dataurl);
    //});
<think>我们正在处理一个关于JavaScript中将Blob对象换为Base64字符串的问题。 根据提供的引用,我们可以从引用[2]和引用[3]中找到相关方法。 引用[2]中提到:可以使用一个工具方法`blobToBase64`,它来自一个工具文件,使用方式如下: import { blobToBase64 } from '@/utils/xxx.js' blobToBase64(blob).then(res => { console.log(res) }).catch(err => { console.log(err) }) 引用[3]中有一个使用FileReader读取Blob(在例子中读取的是File,但File是Blob的子类)为base64的示例: var reader = new FileReader(); reader.readAsDataURL(tempFiles[0]); reader.onload = e => { this.byte_64 = e.target.result.split(';base64,')[1]; // 这里只获取了base64部分,去掉了前面的data:image/png;base64, }; 但是,我们通常需要的是整个DataURL(包括前面的MIME类型和base64编码)还是只要base64字符串?根据问题,用户要求换为Base64字符串,通常指的是去掉前缀的纯base64字符串(如引用[3]中的做法),但有时也可能需要整个DataURL。不过,问题中明确说“Base64字符串”,所以我们可以提供两种方式,并说明区别。 因此,我们可以自己编写一个函数,使用FileReader来读取Blob对象,并返回一个Promise,以便异步获取base64字符串。 步骤: 1. 创建一个FileReader对象。 2. 使用FileReader的readAsDataURL方法读取Blob对象。 3. 在onload事件中,获取读取结果(整个DataURL字符串)。如果只需要纯base64字符串,可以去掉前面的部分(如引用[3]中的split操作),或者也可以返回整个DataURL。 4. 使用Promise封装,因为读取操作是异步的。 根据用户需求,我们提供两种换: a) 返回整个DataURL(例如:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...") b) 返回纯base64字符串(例如:"iVBORw0KGgoAAAANSUhEUg...") 但问题中要求的是“Base64字符串”,通常指的是纯base64编码的字符串,所以我们将重点放在b)上。 实现: 我们可以写一个函数,返回一个Promise,当读取完成时,解析出纯base64字符串。 注意:引用[3]中通过split(';base64,')[1]来获取纯base64字符串,这是因为DataURL的格式是:`data:[<mediatype>][;base64],<data>`。 但是,我们也可以考虑返回整个DataURL,让用户自己决定如何处理。因此,我们可以提供两个函数,或者一个函数通过参数控制。 为了简单和明确,我们将分别实现两个函数: - blobToDataURL(blob): 返回DataURL字符串(包含前缀) - blobToBase64(blob): 返回纯base64字符串 然而,引用[2]中已经有一个名为`blobToBase64`的函数,它返回的是整个DataURL(因为在其示例中,使用`blobToBase64`返回的结果直接打印出来是DataURL,而他们又用了一个`base64ToBlob`来换,所以可能返回的是DataURL)。但是,在引用[2]的示例中,调用`blobToBase64`后打印的是base64,这有点矛盾?实际上,我们再看引用[2]的代码: blobToBase64(blob).then(res => { console.log(res) }) 这里打印的res,根据函数名应该是base64字符串,但根据引用[3]的经验,FileReader.readAsDataURL返回的是DataURL。所以,我们需要确认。 实际上,在引用[2]的代码中,他们的`blobToBase64`函数可能是返回DataURL,也可能是返回纯base64字符串?但他们的注释是“输出blob对象”,然后调用`blobToBase64`,所以这里不明确。 因此,我们按照标准做法: 使用FileReader.readAsDataURL得到的是DataURL字符串。如果我们想要纯base64字符串,需要去掉前面的部分。 所以,我们这样设计: 函数1:blobToDataURL(blob) 返回Promise,解析为完整的DataURL字符串。 函数2:blobToBase64(blob) 返回Promise,解析为纯base64字符串(去掉DataURL前缀)。 但是,我们也可以只提供一个函数,通过参数控制返回类型。但为了清晰,我们分开实现。 实现代码: 1. blobToDataURL(blob) 的实现: function blobToDataURL(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); // reader.result就是DataURL reader.onerror = reject; reader.readAsDataURL(blob); }); } 2. blobToBase64(blob) 的实现: 我们可以利用上面的blobToDataURL,然后处理字符串,或者直接写: function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { // 从DataURL中提取base64部分 const dataURL = reader.result; // 格式为:data:[<mediatype>][;base64],<data> // 我们找到逗号后面的部分 const base64 = dataURL.split(',')[1]; resolve(base64); }; reader.onerror = reject; reader.readAsDataURL(blob); }); } 但是,注意:split(',')[1]这种方法是否可靠?因为DataURL的格式是固定的,逗号前面是头部,后面是数据。所以这样分割是可行的。 另外,引用[3]中使用了split(';base64,'),这是因为他们知道有base64标记,但根据标准,DataURL的格式中,在base64编码的情况下,确实会有“;base64”标记。所以使用split(';base64,')也可以,但这样会包含分号,所以需要取第二部分。两种方法都可以,但split(',')更简单,因为逗号是数据部分的分隔符。 因此,我们采用split(',')的方法。 但是,注意:如果Blob对象不是通过base64编码的?实际上,readAsDataURL方法总是将数据编码为base64格式,并且生成标准的DataURL字符串,其中包含“;base64”标记。所以,使用split(',')取后半部分一定是base64字符串。 所以,我们可以这样写。 另外,我们也可以考虑错误处理。如果读取失败,Promise应该被reject。 现在,我们根据上述思路编写代码。 注意:我们也可以写一个函数,然后通过参数决定返回类型,但为了简单和符合引用[2]中的函数名,我们提供两个函数。 但是,引用[2]中的函数名是`blobToBase64`,它返回的是什么呢?从他们的示例中,调用`blobToBase64`后打印的是一个blob对象?这显然不对,因为注释说输出blob对象,但函数名是base64。实际上,他们的示例可能是这样: const blob = base64ToBlob(base64, 'image/png') // 这个函数是base64字符串blob blobToBase64(blob) // 这个函数是blobbase64 然后他们打印了blob对象(在上一行),然后调用blobToBase64并打印结果(应该是base64字符串)。所以,我们按照函数名,我们的`blobToBase64`应该返回纯base64字符串?还是整个DataURL? 在引用[2]的示例中,他们调用`blobToBase64`后,在then回调中打印res,这个res应该是base64字符串(纯的)?还是DataURL?从他们的注释“输出图片base64”来看,应该是纯base64字符串,因为之前他们用`base64ToBlob`时传入的是纯base64字符串(没有DataURL前缀)。但注意,在`base64ToBlob`函数中,他们需要知道MIME类型,所以单独传了'image/png',而DataURL中是包含MIME类型的。 所以,我们这里有两种选择: a) 如果用户后续需要将base64字符串再Blob,那么需要知道MIME类型,所以返回DataURL(包含MIME类型)可能更方便,因为这样换回来时可以从DataURL中解析出MIME类型。 b) 如果用户只需要base64字符串,并且已经知道MIME类型(或者不需要),那么返回纯base64字符串。 因此,为了通用性,我们可以提供两种方式,并说明使用场景。 但是,用户的问题明确要求:“将Blob对象换为Base64字符串”,通常Base64字符串指的是纯的base64编码,不包含MIME类型。所以,我们主要提供纯base64字符串。 然而,在引用[3]中,他们获取了纯base64字符串,并存储起来,然后在上传时可能需要重新构建成DataURL或者通过multipart上传。所以,我们按照用户需求,提供纯base64字符串。 所以,我们实现`blobToBase64`函数返回纯base64字符串。 另外,我们也可以同时提供`blobToDataURL`,并在说明中解释。 现在,我们编写这两个函数,并给出使用示例。 注意:如果Blob很大,读取操作是异步的,所以使用Promise是合适的。 代码实现: ```javascript // 将Blob对象换为DataURL字符串(包含MIME类型和base64编码) function blobToDataURL(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = function() { resolve(reader.result); // reader.result是一个DataURL字符串 }; reader.onerror = function() { reject(reader.error); }; reader.readAsDataURL(blob); }); } // 将Blob对象换为纯base64字符串(去掉DataURL前缀) function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = function() { // 从DataURL中分割出base64字符串 const dataURL = reader.result; // 格式: "data:[mediatype];base64,[base64数据]" // 我们使用逗号分割,取第二部分 const parts = dataURL.split(','); if (parts.length < 2) { reject(new Error('Invalid DataURL format')); return; } resolve(parts[1]); }; reader.onerror = function() { reject(reader.error); }; reader.readAsDataURL(blob); }); } ``` 使用示例: ```javascript // 假设有一个Blob对象,比如从canvas生成的图片Blob // 使用blobToBase64函数 blobToBase64(blob).then(base64String => { console.log(base64String); // 输出纯base64字符串 }).catch(error => { console.error('换失败', error); }); // 使用blobToDataURL函数 blobToDataURL(blob).then(dataURL => { console.log(dataURL); // 输出完整的DataURL }).catch(error => { console.error('换失败', error); }); ``` 另外,引用[2]中提到了一个工具文件,我们可以将这两个函数封装到一个工具模块中,以便复用。 最后,我们还要注意:在Node.js环境下没有FileReader,所以这些代码只能在浏览器环境中运行。 总结:我们提供了两种换方式,并给出了实现代码和使用示例。</think>### JavaScript中将Blob对象换为Base64字符串的方法 在JavaScript中,将Blob对象换为Base64字符串的核心方法是使用 **`FileReader` API**。以下是详细步骤和实现代码: #### 方法实现 ```javascript function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { // 从DataURL中提取纯Base64字符串(去掉"data:*;base64,"前缀) const base64 = reader.result.split(',')[1]; resolve(base64); }; reader.onerror = () => reject(reader.error); reader.readAsDataURL(blob); // 将Blob读取为DataURL }); } // 使用示例 const blob = new Blob(['Hello, World!'], { type: 'text/plain' }); blobToBase64(blob) .then(base64String => { console.log('Base64字符串:', base64String); // 输出: SGVsbG8sIFdvcmxkIQ== }) .catch(error => { console.error('换失败:', error); }); ``` #### 关键点说明 1. **`FileReader.readAsDataURL()`** 将Blob对象换为DataURL字符串,格式为: `data:<mediatype>;base64,<base64-data>` 例如:`data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==` 2. **提取纯Base64字符串** 通过`split(',')[1]`移除DataURL的前缀,保留纯Base64编码部分。 3. **异步处理** 使用`Promise`封装异步操作,便于通过`.then()`或`async/await`处理结果。 #### 应用场景 - 图片上传前压缩预览 - 将二进制文件通过API传输 - 本地存储二进制数据(如IndexedDB) --- ### 相关问题 1. **如何将Base64字符串换回Blob对象?** ```javascript function base64ToBlob(base64, mimeType) { const byteString = atob(base64); const buffer = new Uint8Array(byteString.length); for (let i = 0; i < byteString.length; i++) { buffer[i] = byteString.charCodeAt(i); } return new Blob([buffer], { type: mimeType }); } ``` 2. **DataURL和纯Base64字符串有何区别?** - **DataURL**:完整格式`data:[<mediatype>][;base64],<data>`,可直接用于`<img src>`或下载链接。 - **纯Base64**:仅包含编码数据,需手动添加MIME类型才能使用[^3]。 3. **大文件换时如何避免内存溢出?** 使用流式处理(如`ReadableStream`)分块读取Blob,但浏览器支持有限,通常需后端配合。 4. **BlobBase64的性能如何优化?** - 对于图片:先使用`canvas`压缩尺寸 - 分块处理:通过`blob.slice()`分割大文件 - Web Worker:避免阻塞主线程 [^1]: BlobBase64互操作的核心API [^2]: 工具库封装示例 [^3]: DataURL结构解析 [^4]: 表单数据传输应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值