pin_drop当前位置:知识文库 ❯ 图文
HTML5 API:HTML5 Blob API - 完整教程与代码示例
一、教程简介
Blob(Binary Large Object)API 是 HTML5 提供的用于处理二进制数据的接口,代表一个不可变的原始数据块。Blob 可以包含任意类型的数据(文本、图片、音视频等),是 File API 的基础,也是处理二进制数据的核心工具。Blob 广泛应用于文件下载、图片处理、数据导出、流式处理等场景。
二、核心概念
Blob 与 File 的关系
代码示例
Blob(原始二进制数据)
├── 属性:size, type
├── 方法:slice(), stream(), text(), arrayBuffer()
└── File(继承 Blob)
├── 额外属性:name, lastModified
└── 通过 <input> 或拖放获取Blob 构造函数
代码示例
const blob = new Blob(blobParts, options);代码示例
// 从字符串创建
const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });
// 从 JSON 创建
const jsonBlob = new Blob([JSON.stringify({ name: '张三' })], { type: 'application/json' });
// 从 HTML 创建
const htmlBlob = new Blob(['<h1>Hello</h1>'], { type: 'text/html' });
// 合并多个 Blob
const combined = new Blob([blob1, blob2, 'extra text'], { type: 'text/plain' });Blob 属性与方法
URL.createObjectURL
代码示例
const url = URL.createObjectURL(blob); // 创建临时 URL
// 使用 URL...
URL.revokeObjectURL(url); // 释放内存三、语法与用法
文件下载
代码示例
function downloadFile(content, filename, type) {
const blob = new Blob([content], { type });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
downloadFile('Hello, World!', 'hello.txt', 'text/plain');
downloadFile(JSON.stringify(data), 'data.json', 'application/json');Blob 读取
代码示例
const blob = new Blob(['Hello'], { type: 'text/plain' });
// 读取为文本
const text = await blob.text();
// 读取为 ArrayBuffer
const buffer = await blob.arrayBuffer();
// 流式读取
const stream = blob.stream();
const reader = stream.getReader();四、代码示例
示例一:文件生成与下载
代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blob API - 文件生成与下载</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #f5f7fa;
min-height: 100vh;
padding: 30px 20px;
}
.container { max-width: 640px; margin: 0 auto; }
h1 { font-size: 24px; color: #2d3436; margin-bottom: 8px; }
.desc { color: #636e72; font-size: 14px; margin-bottom: 24px; }
.card {
background: #fff;
border-radius: 12px;
padding: 24px;
margin-bottom: 16px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}
.card h2 { font-size: 16px; color: #2d3436; margin-bottom: 16px; }
textarea {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 14px;
min-height: 120px;
resize: vertical;
outline: none;
font-family: inherit;
}
textarea:focus { border-color: #0984e3; }
.btn-group { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
button {
padding: 8px 18px;
border: none;
border-radius: 8px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.btn-blue { background: #0984e3; color: #fff; }
.btn-blue:hover { background: #0770c2; }
.btn-green { background: #00b894; color: #fff; }
.btn-green:hover { background: #00a381; }
.btn-orange { background: #fdcb6e; color: #333; }
.btn-orange:hover { background: #e5b85c; }
.btn-purple { background: #a29bfe; color: #fff; }
.btn-purple:hover { background: #8c82f7; }
.preview-area {
background: #f8f9fa;
border-radius: 8px;
padding: 16px;
margin-top: 12px;
min-height: 60px;
font-size: 13px;
color: #333;
}
.preview-img {
max-width: 100%;
max-height: 200px;
border-radius: 8px;
}
.blob-info {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-top: 12px;
}
.info-item {
background: #f8f9fa;
border-radius: 8px;
padding: 12px;
text-align: center;
}
.info-label { font-size: 11px; color: #999; margin-bottom: 4px; }
.info-value { font-size: 16px; font-weight: 700; color: #0984e3; }
</style>
</head>
<body>
<div class="container">
<h1>Blob 文件生成与下载</h1>
<p class="desc">使用 Blob API 生成不同类型的文件并下载。</p>
<div class="card">
<h2>文本文件</h2>
<textarea id="textContent">这是一个使用 Blob API 生成的文本文件。
可以包含多行文本内容。
支持中文和各种特殊字符!@#$%</textarea>
<div class="btn-group">
<button class="btn-blue" onclick="downloadText()">下载 TXT</button>
<button class="btn-green" onclick="downloadCSV()">下载 CSV</button>
<button class="btn-orange" onclick="downloadJSON()">下载 JSON</button>
<button class="btn-purple" onclick="downloadHTML()">下载 HTML</button>
</div>
</div>
<div class="card">
<h2>Canvas 图片导出</h2>
<canvas id="drawCanvas" width="400" height="200" style="width:100%;border:1px solid #eee;border-radius:8px;"></canvas>
<div class="btn-group">
<button class="btn-blue" onclick="downloadCanvasPNG()">下载 PNG</button>
<button class="btn-green" onclick="downloadCanvasJPG()">下载 JPG</button>
<button class="btn-orange" onclick="previewCanvas()">预览</button>
</div>
<div id="canvasPreview"></div>
</div>
<div class="card">
<h2>Blob 信息</h2>
<div class="blob-info" id="blobInfo">
<div class="info-item">
<div class="info-label">大小</div>
<div class="info-value" id="blobSize">--</div>
</div>
<div class="info-item">
<div class="info-label">类型</div>
<div class="info-value" id="blobType">--</div>
</div>
</div>
</div>
</div>
<script>
// 初始化 Canvas
const canvas = document.getElementById('drawCanvas');
const ctx = canvas.getContext('2d');
function drawCanvas() {
const w = canvas.width, h = canvas.height;
const gradient = ctx.createLinearGradient(0, 0, w, h);
gradient.addColorStop(0, '#667eea');
gradient.addColorStop(1, '#764ba2');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, w, h);
ctx.fillStyle = '#fff';
ctx.font = 'bold 28px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('Blob Canvas 导出', w / 2, h / 2 - 10);
ctx.font = '14px sans-serif';
ctx.fillText('点击按钮导出为图片', w / 2, h / 2 + 20);
}
drawCanvas();
function updateBlobInfo(blob) {
document.getElementById('blobSize').textContent = formatSize(blob.size);
document.getElementById('blobType').textContent = blob.type || '未知';
}
function downloadBlob(blob, filename) {
updateBlobInfo(blob);
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
function downloadText() {
const text = document.getElementById('textContent').value;
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
downloadBlob(blob, 'hello.txt');
}
function downloadCSV() {
const data = [
['姓名', '年龄', '城市'],
['张三', '25', '北京'],
['李四', '30', '上海'],
['王五', '28', '广州']
];
const csv = data.map(row => row.join(',')).join('\n');
const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
downloadBlob(blob, 'data.csv');
}
function downloadJSON() {
const data = {
title: 'Blob 示例数据',
items: [
{ id: 1, name: '项目一', status: '完成' },
{ id: 2, name: '项目二', status: '进行中' },
{ id: 3, name: '项目三', status: '待开始' }
],
generated: new Date().toISOString()
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
downloadBlob(blob, 'data.json');
}
function downloadHTML() {
const html = '<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n<meta charset="UTF-8">\n<title>Blob 生成的 HTML</title>\n<style>body{font-family:sans-serif;display:flex;justify-content:center;align-items:center;min-height:100vh;background:#667eea;color:#fff;}</style>\n</head>\n<body>\n<h1>由 Blob API 生成的 HTML 文件</h1>\n</body>\n</html>';
const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
downloadBlob(blob, 'page.html');
}
function downloadCanvasPNG() {
canvas.toBlob(function (blob) {
downloadBlob(blob, 'canvas.png');
}, 'image/png');
}
function downloadCanvasJPG() {
canvas.toBlob(function (blob) {
downloadBlob(blob, 'canvas.jpg');
}, 'image/jpeg', 0.9);
}
function previewCanvas() {
canvas.toBlob(function (blob) {
updateBlobInfo(blob);
const url = URL.createObjectURL(blob);
const preview = document.getElementById('canvasPreview');
preview.innerHTML = '<img src="' + url + '" class="preview-img" alt="预览" style="margin-top:12px;">';
}, 'image/png');
}
function formatSize(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
</script>
</body>
</html>五、浏览器兼容性
六、注意事项与最佳实践
1. 及时释放 ObjectURL
代码示例
const url = URL.createObjectURL(blob);
// 使用完毕后释放
URL.revokeObjectURL(url);
// 否则会造成内存泄漏2. 大文件处理
代码示例
// 使用 stream() 流式处理大 Blob
const stream = blob.stream();
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
// 处理 value(Uint8Array)
}3. Blob 合并
代码示例
// 合并多个 Blob
const merged = new Blob([blob1, blob2, new Uint8Array([1, 2, 3])], {
type: 'application/octet-stream'
});七、代码规范示例
代码示例
class BlobHelper {
static create(content, type = 'text/plain') {
return new Blob([content], { type });
}
static async toDataURL(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
static async toArrayBuffer(blob) {
return blob.arrayBuffer();
}
static async toText(blob) {
return blob.text();
}
static download(blob, filename) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
static slice(blob, start, end, type) {
return blob.slice(start, end, type);
}
static merge(blobs, type = 'application/octet-stream') {
return new Blob(blobs, { type });
}
}八、常见问题与解决方案
常见问题
Q1:Blob URL 在新标签页打开后失效?
解答:Blob URL 只在创建它的文档生命周期内有效。刷新页面后 URL 失效。
Q2:如何将 Base64 转为 Blob?
解决方案:使用 atob 解码 Base64 字符串,然后创建 Uint8Array 并转为 Blob。
代码示例
function base64ToBlob(base64, type = 'image/png') {
const binary = atob(base64.split(',')[1] || base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return new Blob([bytes], { type });
}Q3:如何计算 Blob 的哈希值?
解决方案:使用 crypto.subtle.digest 计算哈希值。
代码示例
async function hashBlob(blob) {
const buffer = await blob.arrayBuffer();
const hash = await crypto.subtle.digest('SHA-256', buffer);
return Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}九、总结
Blob API 是处理二进制数据的核心工具,可以创建、合并、切片和读取二进制数据。配合 URL.createObjectURL 可以实现文件下载和预览,配合 FileReader 可以读取 Blob 内容,配合 Canvas 可以导出图片。使用时需注意及时释放 ObjectURL 防止内存泄漏,大文件使用 stream() 流式处理,以及正确设置 MIME 类型。
标签:
Blob API
二进制数据
文件下载
ObjectURL
File API
本文涉及AI创作
内容由AI创作,请仔细甄别