一、Blob概念
是JavaScript中表示二进制的数据对象
语法
// array: 由ArrayBuffer、ArrayBufferView、Blob、DOMString等对象构成的数组
// options: 可选对象,可以指定MIME类型
const blob = new Blob(array, options);
属性和方法
size:返回Blob对象的大小
type:Blob对象的MIME类型
slice():截取Blob对象的一部分,返回新的Blob对象
text():返回Promise,解析为Blob内容的文本形式
arrayBuffer():返回Promise,解析为Blob内容的ArrayBuffer形式
stream(): 返回ReadableStream,可读取Blob的内容
二、URL概念
用于解析、构造和操作URL,能够将字符串解析为结构化对象,可以轻松访问和修改URL各个部分,比如协议、主机名、路径、查询参数和哈希片段
语法
//url: 要解析的URL字符串
//base: 可选,当url是相对路径时使用
const url = new URL(url,[base])
属性和方法
href:完整URL
protocol:协议
host:主机
port:端口
pathname:路径
search:查询字符串
searchParams:URLSearchParams对象
hash:哈希片段
origin:源
searchParams: 返回一个URLSearchParams对象,用于操作查询字符串API
const params = url.searchParams; const name = params.get(‘name‘); const age = params.get(‘age‘); params.has(‘name‘) // true or false params.append(‘nickname‘, ‘test‘); params.delete(‘gender‘); const strSearch = params.toString(); // 转为字符串
URL.createObjectURL:将Blob或File对象转为一个内存URL
语法:
//object: File、Blob、MediaSource对象 const url = URL.createObjectURL(object);
URL.revokeObjectURL: 释放通过createObjectURL创建的url,从而释放内存
语法:
URL.revokeObjectURL(url);
三、Blob搭配URL.createObjectURL时的使用场景
文件预览及上传
const fileInput = document.querySelector('input[type="file"]') fileInput.addEventListener('change', event => { const file = event.target.files[0]; //文件预览 if(file.type.startWith('image/')) { const img = document.createElement('img'); img.src = URL.createObjectURL(file); document.body.append('img'); } else if(file.startWith('audio/')) { const audio = document.createElement('audio'); audio.src = URL.createObjectURL(file); document.body.append(audio); } else if(file.startWith('video')) { const video = document.createElement('video'); video.src = URL.createObjectURL(file); document.body.append(video); } //文件上传 const formData = new FormData(); formData.append('file', file); fetch('/upload',{ method: 'POST', body: formData }); });
文件生成与下载
//生成txt文件 const text = '这是一个txt文件'; const txtBlob = new Blob([text],{type: 'text/plain;charset=utf-8'}); const txtUrl = URL.createObjectURL(txtBlob); //生成json文件 const json = { name: '这是一个json文件' } const jsonBlob = new Blob([JSON.stringify(json)], {type: 'type: 'application/json'}) const jsonUrl = URL.createObjectURL(jsonBlob); //生成csv文件 const data = [ ['姓名','年龄','城市'], ['张三',28, '北京'], ['李四',29, '上海'], ['王五',30, '深圳'], ] const csvContent = data.map(row => row.join(',')).join('\n'); const csvBlob = new Blob(csvContent,{type: 'text/csv;charset=utf-8'}) const csvUrl = URL.createObjectURL(csvBlob); //下载 const aTxt = documnet.createElement('a'); const aJson = documnet.createElement('a'); const aCsv = documnet.createElement('a'); aTxt.url = txtUrl; aJson.url = jsonUrl; aCsv.url = csvUrl; aTxt.download = '1.txt'; aJson.download = '1.json'; aCsv.download = '1.csv'; document.body.append(aTxt); document.body.append(aJson); document.body.append(aCsv); setTimeout(() => { URL.revokeObjectURL(aTxt); URL.revokeObjectURL(aJson); URL.revokeObjectURL(aCsv); }, 3000);
处理stream
const response = fetch('https://example.com/large-file.mp4');
const stream = response.body;
const reader = stream.getReader();
const chunks = [];
while(true) {
const [done, value] = await reader.read();
if(done) break;
chunks.push(value);
}
const blob = new Blob(chunks, {type: 'video/mp4'});
const videoURL = URL.createObjectURL(blob);
const video = document.createElement('video');
video.src = VideoURL;
document.body.append(video);
四、URL.createObjectURL、FileReader.readAsDataURL、CanvasElement.toDataURL
URL.createObjectURL(blob)
创建一个内存中的URL引用
格式:blob:http://example.com/550e8400-e29b-41d4-a716-446655440000
性能高,不会转为Base64编码
同步操作
需要URL.revokeObjectURL(url)释放内存
FileReader.readAsDataURL(blob)
将Blob内容转为Base64编码的Data URL
格式:data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/...
异步操作,返回Promise
无需手动释放资源
CanvasElement.toDataURL(type, quality)
将canvas内容转换为Base64编码的Data URL
可以指定输出MIME类型和质量
同步操作
const img = new Image(); img.onload = () => { const canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); const dataUrl = canvas.toDataURL('image/jpeg', 0.8); }