六维教程

EdgeOne Makers Blob 存储

图片、视频、文档这类二进制大文件,用 KV 存储不合适,体积大、单值上限 10MB 根本存不下。EdgeOne Makers Blob 存储是专门的对象存储服务,用来存放这类非结构化数据,支持 CDN 加速分发,是文件存储的标准方案。

Blob 存储概念

Blob 的全称是 Binary Large Object,二进制大对象。它允许你把任意类型的文件,图片、视频、备份包、日志文件,统一以”对象”的形式存放在叫做 Bucket 的容器里。

每个对象由三部分组成:

组成部分 说明
Key 对象路径,类似文件名,例如 images/avatar.png
Data 对象内容,二进制流
Metadata 自定义元数据,键值对形式

Blob 存储不关心内容是什么,只负责按 Key 存取,这种简单模型让它能横向扩展到几乎无限的容量。

与 KV 的定位区别

EdgeOne Makers 平台上有 KV 键值存储和 Blob 对象存储,两者各自定位不同。

对比项 Blob 对象存储 KV 键值存储
数据形态 二进制文件、大对象 字符串值
单条上限 单对象最大 5TB 单值 10MB
访问方式 通过 URL 或 API 通过 API
CDN 集成 原生支持 不直接支持
典型场景 图片、视频、文档 配置、缓存、会话

简单记,Blob 存文件、KV 存配置。两者经常配合使用,例如 Blob 存原始图片、KV 存图片元数据。

创建 Bucket

Bucket 是对象的容器,类似一个顶级文件夹。一个账户下可以创建多个 Bucket,相互隔离。

在 EdgeOne Makers 控制台创建:

  1. 进入”存储” -> “Blob”页面
  2. 点击”创建 Bucket”
  3. 输入名称,比如 my-assets
  4. 确认创建

Bucket 名称需要全局唯一,只能用小写字母、数字和短横线,长度 3 到 63 字符。

文件上传

上传文件有两种方式,控制台手动上传和 API 编程上传。

控制台上传

进入 Bucket 详情页,点击”上传”按钮,选择本地文件即可。适合手动测试和小批量维护。

API 上传

在函数代码里上传文件,用 put 方法:

export default {
  async fetch(request, env) {
    if (request.method !== "POST") {
      return new Response("仅支持 POST", { status: 405 });
    }

    // 读取请求体中的文件数据
    const formData = await request.formData();
    const file = formData.get("file");

    if (!file) {
      return Response.json({ error: "缺少 file 字段" }, { status: 400 });
    }

    // 生成唯一路径
    const key = `uploads/${Date.now()}-${file.name}`;

    // 上传到 Blob
    await env.MY_BLOB.put(key, file.stream(), {
      httpMetadata: {
        contentType: file.type,
      },
    });

    return Response.json({ key, size: file.size });
  },
};

字段说明:

字段 说明
key 对象路径,支持用斜杠模拟目录结构
stream 文件的可读流
httpMetadata HTTP 元数据,比如 contentType

文件下载

通过 URL 直接访问

如果 Bucket 开启了公开访问,可以直接通过 URL 下载文件:

https://your-bucket.edgeone.app/images/avatar.png

这种方式最简单,适合公开资源。

通过函数代理下载

如果需要鉴权或控制访问,用函数代理:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const key = url.pathname.slice(1); // 去掉开头的斜杠

    // 从 Blob 读取文件
    const object = await env.MY_BLOB.get(key);

    if (!object) {
      return new Response("文件不存在", { status: 404 });
    }

    // 构造响应
    const headers = new Headers();
    object.writeHttpMetadata(headers);
    headers.set("etag", object.httpEtag);

    return new Response(object.body, { headers });
  },
};

文件列表

列出 Bucket 中的文件:

// 列出所有对象
const list = await env.MY_BLOB.list();

// 按前缀过滤
const images = await env.MY_BLOB.list({ prefix: "images/" });

// 限制返回数量
const limited = await env.MY_BLOB.list({ limit: 100 });

返回结果包含对象的 key、大小、上传时间等信息。

文件删除

删除单个对象:

await env.MY_BLOB.delete("uploads/old-file.png");

删除操作是即时的,删除后无法恢复,谨慎操作。

大文件处理

Blob 存储支持大文件,但上传和下载时需要注意内存和超时问题。

分片上传

对于超过 100MB 的大文件,建议用分片上传,避免单次请求内存爆炸:

// 伪代码示例,实际 API 可能不同
const chunkSize = 5 * 1024 * 1024; // 5MB 一片
let uploadId = await env.MY_BLOB.createMultipartUpload(key);

for (let i = 0; i < totalChunks; i++) {
  const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
  await env.MY_BLOB.uploadPart(key, uploadId, i + 1, chunk);
}

await env.MY_BLOB.completeMultipartUpload(key, uploadId);

流式读取

下载大文件时用流式读取,不要一次性加载到内存:

const object = await env.MY_BLOB.get(key);

// object.body 是 ReadableStream,可以直接 pipe 给响应
return new Response(object.body, {
  headers: {
    "content-type": object.httpMetadata.contentType,
  },
});

这样无论文件多大,内存占用都很小。

最佳实践

路径设计

用斜杠模拟目录结构,方便管理:

好的路径 不好的路径
images/2026/08/avatar.png avatar.png
videos/course/01.mp4 v1.mp4
docs/report-2026.pdf doc.pdf

缓存策略

公开资源配合 CDN 缓存,设置合理的 Cache-Control:

headers.set("cache-control", "public, max-age=31536000");

静态图片、视频这类不常变的内容,缓存时间设长一些,减少回源次数。

访问控制

敏感文件不要开公开访问,用函数代理并加鉴权逻辑。公开资源可以开 CDN 加速,降低源站压力。

速查卡片

要点 说明
Blob 是什么 对象存储,专门存二进制大文件
单文件上限 最大 5TB
适合存什么 图片、视频、文档、备份
访问方式 URL 直接访问或函数代理
CDN 集成 原生支持,适合公开资源分发
大文件处理 分片上传、流式读取
路径设计 用斜杠模拟目录,如 images/2026/avatar.png
访问控制 公开资源开 CDN,敏感文件加鉴权
上一篇
EdgeOne Makers KV 存储
下一篇
EdgeOne Makers 数据库存储