Blob
Overview
EdgeOne Pages Blob is a distributed object storage service designed for Pages Functions. It is suitable for storing unstructured data such as images, documents, and user-uploaded files. By default, it provides fast reads with eventual consistency, allowing the latest value to be read shortly after a write. To read the latest value immediately, you can switch to strong consistency mode for a single read operation.
Note:
The free edition package provides 1GB account storage capacity.
Currently, the Node.js SDK (
@edgeone/pages-blob) is available. SDKs for other runtimes are under development.Blob is designed for the runtime data needs of Pages Functions, such as reading, writing, querying, and processing. It is not recommended for use as a public network image hosting service or CDN.
How It Works
Data access
Blob data is persisted in cloud-based object storage, and its reads are accelerated via edge nodes. Read requests are responded to by the edge node closest to the user, with millisecond-level response times.
Consistency Model
Blob provides two consistency modes, which can be selected as needed:
Mode | Read Behavior | Scenarios |
Eventual Consistency (Default) | Reads from the edge cache, providing the fastest speed. Newly written data requires a brief period (typically seconds) to be read across all nodes. | Content display, cache read, and businesses tolerant of brief inconsistency |
Strong Consistency | Bypasses the cache and reads directly from the primary storage to ensure the latest value is retrieved. The read latency is slightly higher. | Counters, state machines, and businesses that must read the latest written value immediately |
By default,
store.get(key) uses eventual consistency. To switch to strong consistency, pass { consistency: "strong" }. You can also uniformly specify the default consistency for the entire Store when calling getStore.Note:
Strong consistency increases read latency. Use it only when absolutely necessary.
Use Cases
Uploading User Files
It receives files uploaded by users, such as avatars, attachments, and images, stores them in Blob, and organizes them by user or business dimension.
AI-Generated Content
It stores images, documents, and reports generated by AI models, organizes them by batch or type directory, and facilitates search and presentation.
Structured Datasets
Organize multiple JSON files in directories and process the entire dataset by traversing it with
list.Getting Started
1. Installing the SDK
npm install @edgeone/pages-blob
2. Using in Pages Functions
import { getStore } from "@edgeone/pages-blob";export async function onRequest({ request }) {const store = getStore("my-store");// Writeawait store.set("hello.txt", "Hello, EdgeOne Pages!");const content = await store.get("hello.txt");return new Response(content);}
When
getStore("my-store") is called for the first time, the platform automatically creates a namespace named my-store for the current project. Subsequent calls directly use the existing namespace.3. Deployment
After deploying the Pages project, you can view the created namespace and objects on the Blob storage page in the console by triggering a request.
Using the Console
In the console, Blob only supports read-only browsing (viewing namespace lists and browsing object directory structures). Namespace creation and all data operations are performed through the SDK. For details, see the API section below.
API
import { getStore, listStores } from "@edgeone/pages-blob";
getStore(name | options)
Obtain a Store instance.
getStore accepts two types of input parameters:Directly pass in the namespace name string, for example,
getStore("my-store").Pass in a configuration object, for example,
getStore({ name, projectId, token, consistency }).In Pages Functions
Only the namespace name needs to be specified:
const store = getStore("my-store");// You can also use the object form, which makes it convenient to specify a default consistency level at the same time.const store = getStore({ name: "my-store", consistency: "strong" });
Accessing from outside Pages Functions (for example, from local scripts or external services)
The project ID and API Token must be additionally provided:
const store = getStore({name: "my-store",projectId: "pages-urtsvuwmfvli",token: "your-api-token",});
Parameter
Parameter | Type | Required | Description |
name | string | Yes | Namespace Name |
projectId | string | Required when it is accessed outside of Pages Functions | Target Project ID |
token | string | Required when it is accessed outside of Pages Functions | API Token |
consistency | "eventual" | "strong" | No | Default read consistency, default "eventual" |
store.set(key, value, options?)
Writes an object. If the Key already exists, it is overwritten.
await store.set("photos/cat.jpg", imageBuffer);await store.set("notes/todo.txt", "Buy milk");// Prevent overwriting: Writes only when the Key does not exist.await store.set("init.json", data, { onlyIfNew: true });
Parameter
Parameter | Type | Required | Description |
key | string | Yes | The object's Key |
value | string | ArrayBuffer | Blob | ReadableStream | Yes | Object content |
options.onlyIfNew | boolean | No | Writes only when the Key does not exist if set to true. |
Return Value
Promise<void>store.setJSON(key, value, options?)
Writes a JSON object, automatically serializing it. Accepts the same options as
store.set.await store.setJSON("user/preferences", { theme: "dark", lang: "zh-CN" });
Parameter
Parameter | Type | Required | Description |
key | string | Yes | The object's Key |
value | any | Yes | Data that can be serialized to JSON |
options.onlyIfNew | boolean | No | Writes only when the Key does not exist if set to true. |
Return Value
Promise<void>store.get(key, options?)
Reads an object. Returns
null when the Key does not exist.const text = await store.get("hello.txt");const json = await store.get("config.json", { type: "json" });const buffer = await store.get("image.png", { type: "arrayBuffer" });const blob = await store.get("video.mp4", { type: "blob" });const stream = await store.get("large-file.zip", { type: "stream" });// Strongly consistent readconst fresh = await store.get("counter", { consistency: "strong" });
Parameter
Parameter | Type | Required | Description |
key | string | Yes | The object's Key |
options.type | "text" | "json" | "arrayBuffer" | "blob" | "stream" | No | Return value type, default "text" |
options.consistency | "eventual" | "strong" | No | Consistency level for this read operation |
Return Value
Promise<string | object | ArrayBuffer | Blob | ReadableStream | null>store.getWithHeaders(key, options?)
Reads the object content and its complete response headers. Returns
null when the Key does not exist.const result = await store.getWithHeaders("document.pdf");// result.body — object content// result.headers — complete response headers (content-type, etag, cache-control, etc.)
Parameter
Parameter | Type | Required | Description |
key | string | Yes | The object's Key |
options.consistency | "eventual" | "strong" | No | Consistency level for this read operation |
Return Value
Promise<{body: string;headers: Record<string, string>;} | null>
store.delete(key)
Deletes an object. No error is reported when the Key does not exist.
await store.delete("photos/cat.jpg");
Parameter
Parameter | Type | Required | Description |
key | string | Yes | The Key to be deleted |
Return Value
Promise<void>store.list(options?)
Lists objects in a namespace. All pages are automatically aggregated by default.
// Lists all objectsconst { blobs } = await store.list();// Filters by prefixconst { blobs } = await store.list({ prefix: "photos/" });// Groups by directory (returns only files and subdirectories at the current level)const { blobs, directories } = await store.list({prefix: "photos/",directories: true,});// Strong consistencyconst { blobs } = await store.list({ consistency: "strong" });// Manual paginationconst page1 = await store.list({ paginate: false });const page2 = await store.list({ paginate: false, cursor: page1.cursor });
Parameter
Parameter | Type | Required | Description |
options.prefix | string | No | Filtering by Key prefix |
options.directories | boolean | No | When set to true, groups by / and returns the directories field. |
options.paginate | boolean | No | Returns a single page of results (including cursor) when set to false. |
options.cursor | string | No | Continues listing from the cursor of the previous pagination. |
options.consistency | "eventual" | "strong" | No | Consistency level for this listing operation |
Return Value
{blobs: Array<{ key: string; etag: string }>;directories?: string[]; // Returned only when directories: truecursor?: string; // Returned only when paginate: false}
listStores(options?)
Lists all namespaces under the current project.
import { listStores } from "@edgeone/pages-blob";// In Pages Functionsconst { stores } = await listStores();// External accessconst { stores } = await listStores({projectId: "pages-urtsvuwmfvli",token: "your-api-token",});
Parameter
Parameter | Type | Required | Description |
options.projectId | string | Required when it is accessed externally | Target Project ID |
options.token | string | Required when it is accessed externally | API Token |
options.consistency | "eventual" | "strong" | No | Read consistency level |
Return Value
{stores: Array<{ name: string }>;}
Example
Listing Files by Directory
import { getStore } from "@edgeone/pages-blob";export async function onRequest({ request }) {const store = getStore("user-uploads");const url = new URL(request.url);const prefix = url.searchParams.get("path") || "";const { blobs, directories } = await store.list({prefix,directories: true,});return new Response(JSON.stringify({ files: blobs, folders: directories }),{ headers: { "Content-Type": "application/json" } });}
Conditional Write (Prevent Overwrite)
import { getStore } from "@edgeone/pages-blob";export async function onRequest({ request }) {const store = getStore("configs");// Writes only when the Key does not exist, preventing overwriting of existing data.await store.setJSON("app/settings", { version: 1 }, { onlyIfNew: true });const settings = await store.get("app/settings", { type: "json" });return new Response(JSON.stringify(settings), {headers: { "Content-Type": "application/json" },});}