You need to enable JavaScript to run this app.
文档中心
全站加速

全站加速

复制全文
下载 pdf
Agent SDK 参考
对象存储 Blob
复制全文
下载 pdf
对象存储 Blob

本文是 Agent SDK 中对象存储 Blob(对象存储)模块的参考。您可以在服务端读写文件、图片、报告和 JSON 等对象,按 key 组织与检索对象,并为浏览器签发直传上传凭据。本文先给出一段可直接运行的最短示例,随后说明对象 key 的约束、各方法的用途与调用方式、浏览器直传和错误处理。

背景信息

Blob(对象存储)为您的智能体提供在云端读写非结构化对象的能力。无论是持久化生成的文件、保存中间产物,还是为前端签发上传链接,您都可以通过一致的方法接口完成,无需自行管理底层存储资源。

与会话存储、工具、沙箱不同,对象存储是一个独立的包 @iga-pages/blob,而非核心包 @iga-pages/agent 的子路径导出。使用以下方式导入 blob:

import { blob } from "@iga-pages/blob";

blob 导入后可直接使用,导入本身不触发任何运行时初始化;首次调用具体方法时,SDK 才会换取项目身份并建立底层连接。所有 Blob 调用都在 IGA Pages 服务端进行;浏览器需要读写文件时,由应用服务端校验权限后代为调用,或通过下文的直传凭据完成。

前提条件

在调用 Blob 方法前,请确认您已完成以下准备:

Blob 的身份模型与会话存储一致:SDK 会使用当前应用的运行时身份访问对应项目中的资源,项目身份在运行时自动确定,您无需在业务代码或环境变量中传入。

快速开始

导入 blob 后,即可写入和读取内容。下面这段代码是使用对象存储的最短闭环:写入一个文本对象,再用相同的 key 读回它。

import { blob } from "@iga-pages/blob";

await blob.set("reports/daily/report.md", "# 分析报告");

const report = await blob.get("reports/daily/report.md");
console.log(report); // "# 分析报告"

写入与读取都以对象 key 为标识,无需提前创建目录或初始化存储资源。确认这一最短闭环可用后,再按下文展开更完整的读写、列举与直传能力。

存储范围与对象 key

key 是对象在当前项目内的名称,例如 reports/daily/report.md。后续请求使用相同的 key 即可访问该对象;底层存储按项目隔离,您无需关心物理路径或存储桶。

可以用 / 组织 key,无需提前创建目录。例如,reports/daily/ 可作为前缀,用于筛选一组报告。key 不是下载地址。

await blob.set("reports/daily/report.md", "# 每日报告");

const reports = await blob.list({ prefix: "reports/daily/" });
console.log(reports.blobs);

key 不能为空,不能以 / 开头或结尾,也不能包含反斜杠、空字符(NUL)、连续的 /,或单独的 .、.. 路径段。返回的 key 保留完整前缀,可直接用于读取、查询和删除。

数据模型

在查阅方法之前,先了解 Blob 读写涉及的核心对象与类型。

BlobObject(对象元信息)字段如下:

字段类型说明
keystring对象键(在存储桶内的路径标识)。
etagstring?对象内容标识,可用于校验版本。
sizenumber?对象字节大小。
contentTypestring?对象的内容类型(MIME)。
lastModifiedstring?最近修改时间。

写入正文类型 BlobBody 可取:string、ArrayBuffer、ArrayBufferView、Blob、ReadableStream<Uint8Array>。

读取格式 BlobReadFormat 可取:text、json、arrayBuffer、blob、stream;缺省为 text。

管理对象

BlobStore 公开以下方法。具体参数、参数位置和返回类型,请查看对应方法签名:在编辑器中悬停方法名,或跳转到类型定义即可查看。

方法用途
blob.set()写入文本、二进制内容或数据流
blob.setJSON()将数据保存为 JSON
blob.get()读取对象内容
blob.info()查询对象信息
blob.list()列出对象,支持按 key 前缀筛选
blob.delete()删除对象
blob.createUploadUrl()生成临时上传凭据,供浏览器直接上传文件

各方法异步返回结果,失败时抛出异常,处理方式见请求与错误处理。createUploadUrl() 的使用示例见浏览器直接上传。

set:写入对象

使用 blob.set() 保存文本、二进制内容或数据流。默认覆盖相同 key 的对象。

const object = await blob.set("reports/daily/report.md", "# 分析报告", {
  contentType: "text/markdown",
});

console.log(object.key);

写入成功后返回对象信息(BlobObject)。contentType 是可选的 MIME 类型,明确传入时原样交给底层存储。需要避免覆盖已有对象时,设置 onlyIfNew: true;同名对象存在时不会被覆盖,调用会抛出 BlobError。

setJSON:写入 JSON

使用 blob.setJSON() 保存可序列化为 JSON 的数据,无需手动转换为字符串或指定内容类型。

await blob.setJSON("reports/daily/result.json", {
  total: 5050,
});

默认覆盖相同 key 的对象,也可通过 onlyIfNew: true 限制为仅新建。成功后返回对象信息;数据无法序列化为 JSON 时抛出 BlobError(code 为 BadRequest)。

get:读取对象

使用 blob.get() 读取内容,默认返回文本;对象不存在时返回 null。

const report = await blob.get("reports/daily/report.md");
if (report === null) {
  console.log("报告不存在");
} else {
  console.log(report);
}

读取 JSON 时指定 format: "json",并可用泛型标注返回结构:

const result = await blob.get<{ total: number }>("reports/daily/result.json", {
  format: "json",
});
console.log(result?.total); // 5050

还支持 arrayBuffer、blob 和 stream 读取格式。JSON 内容无效时会抛出 BlobError(code 为 BadRequest);泛型只提供 TypeScript 类型提示,不校验数据的业务结构。浏览器需要读取文件时,由应用服务端校验权限、调用 get(),再通过应用接口返回内容。

info:读取对象信息

使用 blob.info() 查询对象信息,不读取正文;对象不存在时返回 null。

const object = await blob.info("reports/daily/report.md");
if (object !== null) {
  console.log(object.key, object.size);
}

返回信息包含 key,以及可选的 size(字节数)、contentType、etag 和 lastModified。

list:列出对象

使用 blob.list() 列出当前项目的对象,可通过 prefix 按 key 前缀筛选。对象列表位于返回结果的 blobs 中。

const result = await blob.list({ prefix: "reports/daily/" });
for (const object of result.blobs) {
  console.log(object.key);
}

默认自动读取全部分页。需要逐页读取时,设置 paginate: false,并用返回的 cursor 获取下一页:

const page = await blob.list({
  prefix: "reports/daily/",
  paginate: false,
});

if (page.cursor) {
  const nextPage = await blob.list({
    prefix: "reports/daily/",
    paginate: false,
    cursor: page.cursor,
  });
  console.log(nextPage.blobs);
}

没有 cursor 时表示没有下一页。翻页时保持 prefix 和 directories 选项一致。需要按目录浏览时,设置 directories: true:直接子目录汇总在 directories 中,目录内的文件不再展开到 blobs。

delete:删除对象

使用 blob.delete() 删除对象:

await blob.delete("reports/daily/report.md");

删除成功后无返回数据。对象不存在或重复删除时也会成功;删除失败时抛出异常。

浏览器直接上传

使用 blob.createUploadUrl() 在服务端生成临时上传凭据,再由浏览器直接上传文件内容,避免大文件经过应用服务器中转。

服务端先校验用户权限并确定允许写入的 key,再生成凭据:

import { randomUUID } from "node:crypto";
import { blob } from "@iga-pages/blob";

export async function createUploadTicket() {
  return blob.createUploadUrl(`uploads/${randomUUID()}.bin`, {
    onlyIfNew: true,
  });
}

凭据(BlobUploadTicket)包含 key、url、method 和 expiresAt。其中 method 固定为 "PUT",expiresAt 是以秒为单位的 Unix 时间戳。将凭据返回给浏览器,并在有效期内上传:

type UploadTicket = {
  key: string;
  url: string;
  method: "PUT";
  expiresAt: number;
};

export async function uploadFile(ticket: UploadTicket, file: File) {
  const response = await fetch(ticket.url, {
    method: ticket.method,
    body: file,
  });
  if (!response.ok) {
    throw new Error(`上传失败:${response.status}`);
  }
  return ticket.key;
}

生成凭据不代表上传完成,应以浏览器上传请求成功为准。保存返回的 key,供后续读取文件。凭据过期后,重新向服务端申请。

默认允许覆盖相同 key 的对象;示例通过 onlyIfNew: true 避免覆盖。

取消浏览器上传时,在该次 fetch() 中传入 signal。

请求与错误处理

Blob 方法直接返回结果,失败时抛出异常。使用 try...catch 捕获 BlobError,其结构为 { code, status?, message }:

import { blob, BlobError } from "@iga-pages/blob";

export async function saveOnce(key: string, content: string) {
  try {
    return await blob.set(key, content, { onlyIfNew: true });
  } catch (error) {
    if (error instanceof BlobError) {
      console.error(error.toJSON());
    }
    throw error;
  }
}

code 是字符串错误码,可能来自 SDK 本地校验、网络层或上游服务;不要假设所有值都属于同一组 HTTP 分类。status 仅在 SDK 能取得 HTTP 状态时出现。

各模块的错误处理方式不同。处理 Blob 错误时,先用 instanceof BlobError 判断,再读取其字段。

对象不存在时,get() / info() 返回 null、delete() 视为成功,不会抛出 BlobError。

需要取消操作或限制等待时间时,通过请求选项传入 abortSignal:

const report = await blob.get("reports/daily/report.md", {
  abortSignal: AbortSignal.timeout(10_000),
});

取消会停止当前操作的等待、后续分页和响应流读取,不会回滚已经完成的写入。

最近更新时间:2026.10.08 11:53:16
这个页面对您有帮助吗?
有用
有用
无用
无用