EdgeOne Makers Storage 是 EdgeOne Pages 为 Makers Functions 提供的数据持久化存储能力,分为 KV(键值)存储与 Blob(对象)存储两种。以下按用途与使用方式分别说明。
一、KV 存储
【用途】EdgeOne Pages KV 是部署在多个边缘节点的全球分布式键值持久化存储服务,数据采用最终一致性模型,并在 60 秒内完成全球同步。适合保存简单键值对数据。
【重要限制】KV 存储仅在 Edge Functions 中可用,不支持 Node Functions。
【使用前置条件】在编写任何代码前,必须先在 EdgeOne Pages 控制台开通 KV 存储: 第一步,启用 KV 存储:登录 EdgeOne Pages 控制台,进入“KV Storage”页面,点击“Apply Now”激活(免费额度包含 1 GB 存储)。 第二步,创建命名空间:命名空间是数据隔离单元(类似独立数据库)。在“KV Storage”页面点击“Create Namespace”,输入名称(如 my-kv-store),等待创建完成。一个账号最多可创建 10 个命名空间。 第三步,将命名空间绑定到项目并设置变量名:方式 A,从 KV Storage 页面打开命名空间,进入“Associated Projects”标签,点击“Bind Project”,选择项目并设置变量名(如 my_kv);方式 B,从项目设置中打开项目详情,进入“KV Storage”菜单,点击“Bind Namespace”,选择命名空间并设置变量名。该变量名会成为 Edge Function 代码中的全局变量,不同命名空间可使用不同变量名。
【核心概念】KV 命名空间通过全局变量访问,而不是 context.env。资料明确指出:错误写法是 context.env.KV;正确写法是直接使用绑定时设置的全局变量名(如 my_kv.get('key'))。
【API 参考】所有方法均在全局 KV 变量(如 my_kv)上调用:
- put:put(key, value),写入数据。key 长度 ≤ 512 字节,仅允许字母数字与下划线;value 支持 string、ArrayBuffer、ArrayBufferView、ReadableStream,大小 ≤ 25 MB;返回 Promise,需 await 确认写入。
- get:get(key, type?),读取数据。type 默认 'text',可选 'json' 自动反序列化、'arrayBuffer'、'stream';键不存在时返回 null。
- delete:delete(key),删除数据,返回 Promise。
- list:list(options?),枚举键,支持 prefix、limit、cursor 选项。返回 ListResult,包含 complete(是否已返回全部键)、cursor(下一页游标)、keys(键名数组)。支持单页查询与循环分页获取全部键。
【示例】资料提供了三个示例:页面访问计数器(读取 page_views、递增后写回并返回 JSON);基于 KV 的 CRUD(通过 user:{id} 键实现 GET/POST/DELETE);按前缀列出所有键并批量读取(使用 list 分页配合 Promise.all)。
【常见错误】资料列出以下症状、原因与修复方式:ReferenceError: my_kv is not defined(KV 未启用或命名空间未绑定,需在控制台启用、创建命名空间并绑定项目);访问 context.env.KV 返回 undefined(KV 是全局变量而非 context.env 上的属性,应直接使用 my_kv);get() 返回 Promise 对象而非值(缺少 await,所有 KV 操作都应 await);本地可用但生产失败或反之(项目未关联,需运行 edgeone pages link);KV 在 Node Functions 中不可用(KV 仅在 Edge Functions 中工作,需将 KV 逻辑迁至 Edge Functions,或在 Node Functions 中使用外部数据库)。
【限制】每账号免费额度存储 1 GB;键长度 ≤ 512 字节;值大小 ≤ 25 MB;每账号命名空间 10 个;一致性为最终一致(全球同步 ≤ 60 秒);每次 list 返回最多 256 条;支持运行时仅 Edge Functions。
【最佳实践】使用键前缀组织数据(如 user:123、cart:456、config:theme);处理 null(get() 对缺失键返回 null);在 list() 之后用 Promise.all() 批量读取而非顺序 await;写入始终用 try/catch 包裹;对象序列化使用 JSON.stringify() 写入、读取时用 'json' 类型。
【本地开发】依次运行:edgeone pages link(关联远程项目,KV 访问必需)、edgeone pages dev(启动开发服务器)、curl http://localhost:8088/api/counter(测试)。
【生产部署】在控制台启用 KV 存储、创建命名空间、绑定到项目(设置变量名),然后执行 edgeone pages deploy。
二、Blob 存储
【用途】面向 Makers Functions 的分布式对象存储,适合图片、文档、用户上传、AI 生成内容等。限制:免费账号 1 GB 存储;目前仅提供 Node.js SDK(@edgeone/pages-blob)。
【安装】npm install @edgeone/pages-blob
【获取 Store】使用 getStore:在 Makers Functions 中自动配置,可传名称字符串,也可传对象并指定一致性,如 consistency: "strong"。
【一致性模型】"eventual"(默认):边缘缓存、最快、数据数秒内同步,适用于内容展示、可容忍短暂陈旧;"strong":绕过缓存、从主存储读取,适用于计数器、状态机等必须读取最新值的场景。
【API 参考】store.set(key, value, opts?) 写入对象(string / ArrayBuffer / Blob / ReadableStream);store.setJSON(key, value, opts?) 写入 JSON(自动序列化);store.get(key, opts?) 读取对象(未找到返回 null);store.getWithHeaders(key, opts?) 读取并返回响应头(etag、content-type);store.delete(key) 删除对象;store.list(opts?) 列出对象(前缀过滤、目录分组、分页);store.createUploadUrl(key, opts?) 生成预签名 PUT URL 供客户端直传。
【写入示例】set 写入图片缓冲区或文本;setJSON 写入 JSON;可通过 { onlyIfNew: true } 仅在键不存在时写入。
【读取示例】get 可返回 string,或通过 type 指定 'json'(解析为对象)、'arrayBuffer'、'stream';也可通过 consistency: "strong" 进行强一致读取。type 选项包括 'text'(默认)、'json'、'arrayBuffer'、'blob'、'stream'。
【列表】可列出全部对象、按前缀列出、开启目录分组(返回 blobs 与 directories),或使用 paginate: false 与 cursor 手动分页。
【客户端直传】通过 createUploadUrl 生成预签名 URL,用于不经 Functions 的大文件上传,可设置 expireSeconds 与 contentType;客户端直接向该 url 发起 PUT。
【删除】store.delete(key),键不存在时静默处理。
【列出所有 Store】使用 listStores(从 @edgeone/pages-blob 导入),返回 stores 数组,包含各 store 名称。