可直接用 fetch 获取远程二进制资源并转为 Blob 下载或解析,关键在于正确设置请求头、响应类型及合理使用 Blob API;需避免内容协商干扰、禁用 .json()/.text() 解析,改用 .blob() 或 .arrayBuffer(),注意 CORS 限制与 download 属性触发条件。

可以直接用 fetch 获取远程二进制资源,转为 Blob 后下载或解析,无需服务端中转,关键在于正确设置请求头、选择响应类型,并合理使用 Blob API。
确保 fetch 请求返回二进制数据
默认情况下,fetch 的响应体是流式可读的,但要准确拿到原始字节,需注意两点:
- 不设置
Accept头或显式设为*/*,避免服务器因内容协商返回非二进制格式(如 base64 或 HTML 错误页) - 不要用
.json()、.text()等方法解析,改用.blob()或.arrayBuffer()
示例:
const res = await fetch('https://example.com/image.png');
const blob = await res.blob(); // ✅ 正确:直接获取 Blob
用 Blob 下载文件(触发浏览器保存)
生成临时 URL 并模拟点击链接是最兼容的方式:
- 调用
URL.createObjectURL(blob)创建本地引用地址 - 创建
元素,设置href和download属性(后者指定保存的文件名) - 触发点击后,记得调用
URL.revokeObjectURL()释放内存
完整示例:
async function downloadFile(url, filename) {
const res = await fetch(url);
const blob = await res.blob();
const urlObj = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = urlObj;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(urlObj); // ⚠️ 必须释放
}
解析 Blob 内容(如读取图片尺寸、PDF 元信息等)
Blob 本身不可直接读取内容,需转为更底层的格式:
-
blob.arrayBuffer()→ 得到ArrayBuffer,适合解析二进制结构(如 PNG 头、ZIP 目录、PDF 版本号) -
new FileReader().readAsArrayBuffer(blob)→ 兼容性更好,适用于需要回调的旧环境 - 对图像类 Blob,也可用
URL.createObjectURL(blob)+加载后读取naturalWidth/naturalHeight
读取 PNG 宽高的简单示例(基于前 24 字节):
async function getPngSize(blob) {
const buf = await blob.arrayBuffer();
const view = new DataView(buf);
if (view.getUint32(0) !== 0x89504e47) return null; // PNG signature
const width = view.getUint32(16);
const height = view.getUint32(20);
return { width, height };
}
注意事项与常见问题
CORS 是最大拦路虎 —— 若目标服务器未设置 Access-Control-Allow-Origin,fetch 会失败。此时无法绕过(除非服务端配合或使用代理)。
- 大文件建议加 loading 状态,
Blob构建本身不耗时,但网络和解析可能卡顿 - 部分浏览器对
download属性有策略限制(如跨域链接、非用户手势触发),优先在点击事件中调用下载逻辑 -
Blob是只读引用,修改内容需重新构造,例如裁剪图片需先解码再编码为新 Blob










