简介
涉及数据类型
- blob、file
- ObjectURL
- DataURL、text、BinaryString、ArrayBuffer
blob、file
blob、file 来源
通常我们得到File和Blob对象,总结有这几种方式:
- 通过input标签
- 通过接口获取
- 拖拽方式
- canvas获取
input获取file
<input type="file" name="file" id="file">
const inputNode = document.getElementById('file')
inputNode.addEventListener('change', (e) => {
const file = e.target.files[0]
})
接口获取blob
接口获取需要设置响应头为blob,这里以axios和fetch为例
axios
axios.post(url,{
// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'blob',
})
fetch
fetch(url).then(res=>{
// 常用的有 json、text、arrayBuffer、blob
return res.blob()
})
拖拽获取文件
<div style="background: #22e7d7; width: 500px; height: 500px; margin: 20px auto">
<div id="drag" style="width: 100%; height: 100%"></div>
</div>
const dragNode = document.getElementById("drag");
dragNode.ondragover = (e) => {
e.preventDefault();
};
dragNode.ondrop = (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
console.log(files);
};
canvas获取blob
<canvas id="canvas"></canvas>
const canvas = document.getElementById("canvas");
canvas.toBlob((blob) => {
console.log(blob);
});
blob和file之间的关系
创建blob
new Blob(array, options);
参数
array:数组,由ArrayBuffer、ArrayBufferView、Blob、DOMString等对象构成的,将会被放进Blob;options:对象,可以指定如下两个属性type:默认值为 "",表示将会被放入到blob中的数组内容的 MIME 类型。endings:默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入,不常用。
常见的 MIME 类型如下:
| 类型 | 描述 |
|---|---|
| text/plain | 纯文本文档 |
| text/html | HTML文档 |
| text/javascript | JavaScript文件 |
| text/css | CSS文件 |
| application/json | JSON文件 |
| application/pdf | PDF文件 |
| application/xml | XML文件 |
| image/jpeg | JPEG图像 |
| image/png | PNG图像 |
| image/svg+xml | SVG图像 |
| audio/mpeg | MP3文件 |
| video/mpeg | MP4文件 |
ObjectURL
Object URL又称Blob URL(W3C定义名称),是HTML5中的新标准。它是一个用来表示File Object 或Blob Object 的URL。在网页中,我们可能会看到过这种形式的 blob: URL
其实Blob URL/Object URL 是一种伪协议,允许将 Blob 和 File 对象用作图像、二进制数据下载链接等的 URL 源。
对于 Blob/File 对象,可以使用 URL构造函数的 createObjectURL() 方法创建将给出的对象的 URL。这个 URL 对象表示指定的 File 对象或 Blob 对象。我们可以在<img>、<script> 标签中或者 <a> 和 <link> 标签的 href 属性中使用这个 URL(可以用于实现下载文件)
DataURL、text、BinaryString、ArrayBuffer
Data URL
Data URL是一种包含数据的URL,其中数据部分通常是使用Base64编码的。是一种将小数据嵌入到文档中的方式。它的格式如下:
data:[<mediatype>][;base64],<data>
<mediatype>:表示数据的媒体类型(MIME 类型),例如text/plain或image/png。如果省略,默认值是text/plain;charset=US-ASCII。;base64:表示数据使用 Base64 编码。如果省略,数据部分应为 URL 编码的字符串。<data>:表示实际的数据部分。
Base64
Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。Base64 编码普遍应用于需要通过被设计为处理文本数据的媒介上储存和传输二进制数据而需要编码该二进制数据的场景。这样是为了保证数据的完整并且不用在传输过程中修改这些数据。
在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:
atob():解码,解码一个 Base64 字符串;btoa():编码,从一个字符串或者二进制数据编码一个 Base64 字符串。
总结一下:
- Data URL 是一种将数据嵌入到文档中的 URL 格式,其中数据部分通常使用 Base64 编码。
- Base64 是一种将二进制数据转换为 ASCII 字符串的编码方式,用于在文本环境中传输二进制数据。
生成Data URL的两种方式
canvas生成DataURL:
const dataUrl = canvas.toDataURL();
使用FileReader的readAsDataURL:
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
console.log(e.target.result);
}
Text
字面意思,就是文本
BinaryString
BinaryString指的是以二进制形式表示的数据,并用字符串的方式来存储和操作。这意味着它是一个由字符 '0' 和 '1' 组成的字符串,代表二进制数。
ArrayBuffer
ArrayBuffer 是 JavaScript 中用于处理二进制数据的对象。它代表一个通用的、固定长度的原始二进制数据缓冲区,可以用于处理各种类型的二进制数据,如图像、音频、网络协议等。
数据转换
blob、file转ObjectURL
经典下载代码
// 使用 URL.createObjectURL 创建一个 URL 对象
const url = URL.createObjectURL(blob);
// 创建一个 <a> 标签并设置下载属性
const a = document.createElement('a');
a.href = url;
a.download = 'hello.txt'; // 设置下载的文件名
// 模拟点击 <a> 标签
document.body.appendChild(a);
a.click();
// 移除 <a> 标签并释放 URL 对象
document.body.removeChild(a);
URL.revokeObjectURL(url);
blob、file转DataURL、Text、BinaryString、ArrayBuffer
FileReader
先了解一下FileReader:
FileReader 允许异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据(也就是可以将blob、file转换成其他数据类型)
blob、file转DataURL
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
console.log(e.target.result);
}
blob、file转Text
const reader = new FileReader();
reader.readAsText(blob);
reader.onload = function (e) {
console.log(e.target.result);
}
blob、file转BinaryString
const reader = new FileReader();
reader.readAsBinaryString(blob);
reader.onload = function (e) {
console.log(e.target.result);
}
blob、file转ArrayBuffer
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = function (e) {
console.log(e.target.result);
}
DataURL、Text、BinaryString、ArrayBuffer四种数据的互相转换
Data URL转换其他三种格式
DataURL -> ArrayBuffer
function dataURLToArrayBuffer(dataURL) {
const binaryString = atob(dataURL.split(',')[1]);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
DataURL -> BinaryString
function dataURLToBinaryString(dataURL) {
return atob(dataURL.split(',')[1]);
}
DataURL -> Text
async function dataURLToText(dataURL) {
const arrayBuffer = dataURLToArrayBuffer(dataURL);
return arrayBufferToText(arrayBuffer);
}
ArrayBuffer转换其他三种格式
ArrayBuffer -> DataURL
function arrayBufferToDataURL(arrayBuffer, mimeType = 'application/octet-stream') {
const bytes = new Uint8Array(arrayBuffer);
const binaryString = bytes.reduce((data, byte) => data + String.fromCharCode(byte), '');
return `data:${mimeType};base64,${btoa(binaryString)}`;
}
ArrayBuffer -> BinaryString
function arrayBufferToBinaryString(arrayBuffer) {
const bytes = new Uint8Array(arrayBuffer);
return bytes.reduce((data, byte) => data + String.fromCharCode(byte), '');
}
ArrayBuffer -> Text
function arrayBufferToText(arrayBuffer) {
const decoder = new TextDecoder('utf-8');
return decoder.decode(new Uint8Array(arrayBuffer));
}
BinaryString转换其他三种格式
BinaryString -> ArrayBuffer
function binaryStringToArrayBuffer(binaryString) {
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
BinaryString -> DataURL
function binaryStringToDataURL(binaryString, mimeType = 'application/octet-stream') {
return `data:${mimeType};base64,${btoa(binaryString)}`;
}
BinaryString -> Text
function binaryStringToText(binaryString) {
return decodeURIComponent(escape(binaryString));
}
Text转换其他三种格式
Text -> ArrayBuffer
function textToArrayBuffer(text) {
const encoder = new TextEncoder();
return encoder.encode(text).buffer;
}
Text -> BinaryString
function textToBinaryString(text) {
return unescape(encodeURIComponent(text));
}
Text -> DataURL
function textToDataURL(text, mimeType = 'text/plain') {
const arrayBuffer = textToArrayBuffer(text);
return arrayBufferToDataURL(arrayBuffer, mimeType);
}
通过上述函数,可以实现 Data URL、ArrayBuffer、Binary String 和 Text 之间的相互转换。注意在处理不同编码格式和数据类型时,需要根据具体需求调整 TextDecoder 和 TextEncoder 的编码参数。
DataURL、Text、BinaryString、ArrayBuffer四种格式转换为blob格式
DataURL -> Blob
function dataURLToBlob(dataURL) {
const byteString = atob(dataURL.split(',')[1]);
const mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0];
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: mimeString });
}
ArrayBuffer -> Blob
function arrayBufferToBlob(arrayBuffer, mimeType = 'application/octet-stream') {
return new Blob([arrayBuffer], { type: mimeType });
}
BinaryString -> Blob
function binaryStringToBlob(binaryString, mimeType = 'application/octet-stream') {
const ab = new ArrayBuffer(binaryString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < binaryString.length; i++) {
ia[i] = binaryString.charCodeAt(i);
}
return new Blob([ia], { type: mimeType });
}
Text -> Blob
function textToBlob(text, mimeType = 'text/plain') {
return new Blob([text], { type: mimeType });
}