workers-runtime-apis
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare Workers Runtime APIs
Cloudflare Workers Runtime API
Master the Workers runtime APIs: Fetch, Streams, Crypto, Cache, WebSockets, and text encoding.
熟练掌握Workers运行时API:Fetch、Streams、Crypto、Cache、WebSockets和文本编码。
Quick Reference
快速参考
| API | Purpose | Common Use |
|---|---|---|
| Fetch | HTTP requests | External APIs, proxying |
| Streams | Data streaming | Large files, real-time |
| Crypto | Cryptography | Hashing, signing, encryption |
| Cache | Response caching | Performance optimization |
| WebSockets | Real-time connections | Chat, live updates |
| Encoding | Text encoding | UTF-8, Base64 |
| API | 用途 | 常见场景 |
|---|---|---|
| Fetch | HTTP请求 | 调用外部API、代理 |
| Streams | 数据流传输 | 大文件处理、实时传输 |
| Crypto | 加密运算 | 哈希计算、签名、加密 |
| Cache | 响应缓存 | 性能优化 |
| WebSockets | 实时连接 | 聊天、实时更新 |
| Encoding | 文本编码 | UTF-8、Base64处理 |
Quick Start: Fetch API
快速上手:Fetch API
typescript
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Basic fetch
const response = await fetch('https://api.example.com/data');
// With options
const postResponse = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${env.API_KEY}`,
},
body: JSON.stringify({ name: 'John' }),
});
// Clone for multiple reads
const clone = response.clone();
const json = await response.json();
const text = await clone.text();
return Response.json(json);
}
};typescript
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// 基础fetch调用
const response = await fetch('https://api.example.com/data');
// 带参数的请求
const postResponse = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${env.API_KEY}`,
},
body: JSON.stringify({ name: 'John' }),
});
// 克隆响应以支持多次读取
const clone = response.clone();
const json = await response.json();
const text = await clone.text();
return Response.json(json);
}
};Critical Rules
核心规则
- Always set timeouts for external requests - Workers have a 30s limit, external APIs can hang
- Clone responses before reading body - Body can only be read once
- Use streaming for large payloads - Don't buffer entire response in memory
- Cache external API responses - Reduce latency and API costs
- Handle Crypto operations in try/catch - Invalid inputs throw errors
- WebSocket hibernation for cost - Use Durable Objects with hibernation
- 外部请求务必设置超时 - Workers有30秒运行限制,外部API可能挂起
- 读取响应体前先克隆 - 响应体仅可读取一次
- 大负载使用流传输 - 不要将整个响应缓冲到内存中
- 缓存外部API响应 - 降低延迟和API调用成本
- 在try/catch中处理Crypto操作 - 无效输入会抛出错误
- 使用WebSocket休眠降低成本 - 搭配支持休眠的Durable Objects使用
Top 10 Errors Prevented
可避免的10大常见错误
| Error | Symptom | Prevention |
|---|---|---|
| Body already read | | Clone response before reading |
| Fetch timeout | Request hangs, worker times out | Use |
| Invalid JSON | | Check content-type before parsing |
| Stream locked | | Don't read stream multiple times |
| Crypto key error | | Validate key format and algorithm |
| Cache miss | Returns | Check cache before returning |
| WebSocket close | Connection drops unexpectedly | Handle close event, implement reconnect |
| Encoding error | | Use TextEncoder/TextDecoder properly |
| CORS blocked | Browser rejects response | Add proper CORS headers |
| Request size | | Stream large uploads |
| 错误 | 表现 | 预防方案 |
|---|---|---|
| 响应体已被读取 | | 读取前先克隆响应 |
| Fetch超时 | 请求挂起,worker运行超时 | 搭配 |
| 无效JSON | | 解析前先检查content-type |
| 流被锁定 | | 不要多次读取同一个流 |
| Crypto密钥错误 | | 校验密钥格式和算法是否匹配 |
| 缓存未命中 | 返回 | 返回前先检查缓存是否存在 |
| WebSocket断开 | 连接意外中断 | 处理close事件,实现重连逻辑 |
| 编码错误 | | 正确使用TextEncoder/TextDecoder |
| CORS拦截 | 浏览器拒绝响应 | 添加正确的CORS头 |
| 请求过大 | | 流式传输大体积上传内容 |
Fetch API Patterns
Fetch API 常用模式
With Timeout
带超时实现
typescript
async function fetchWithTimeout(url: string, timeout: number = 5000): Promise<Response> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
return response;
} finally {
clearTimeout(timeoutId);
}
}typescript
async function fetchWithTimeout(url: string, timeout: number = 5000): Promise<Response> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
return response;
} finally {
clearTimeout(timeoutId);
}
}With Retry
带重试实现
typescript
async function fetchWithRetry(
url: string,
options: RequestInit = {},
retries: number = 3
): Promise<Response> {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.ok) return response;
// Retry on 5xx errors
if (response.status >= 500 && i < retries - 1) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
continue;
}
return response;
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
throw new Error('Max retries exceeded');
}typescript
async function fetchWithRetry(
url: string,
options: RequestInit = {},
retries: number = 3
): Promise<Response> {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.ok) return response;
// 5xx错误时重试
if (response.status >= 500 && i < retries - 1) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
continue;
}
return response;
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
throw new Error('Max retries exceeded');
}Streams API
Streams API
Transform Stream
转换流
typescript
function createUppercaseStream(): TransformStream<string, string> {
return new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk.toUpperCase());
}
});
}
// Usage
const response = await fetch('https://example.com/text');
const transformed = response.body!
.pipeThrough(new TextDecoderStream())
.pipeThrough(createUppercaseStream())
.pipeThrough(new TextEncoderStream());
return new Response(transformed);typescript
function createUppercaseStream(): TransformStream<string, string> {
return new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk.toUpperCase());
}
});
}
// 使用示例
const response = await fetch('https://example.com/text');
const transformed = response.body!
.pipeThrough(new TextDecoderStream())
.pipeThrough(createUppercaseStream())
.pipeThrough(new TextEncoderStream());
return new Response(transformed);Stream Large Response
大响应流处理
typescript
async function streamLargeFile(url: string): Promise<Response> {
const response = await fetch(url);
// Stream directly without buffering
return new Response(response.body, {
headers: {
'Content-Type': response.headers.get('Content-Type') || 'application/octet-stream',
},
});
}typescript
async function streamLargeFile(url: string): Promise<Response> {
const response = await fetch(url);
// 直接流式传输无需缓冲
return new Response(response.body, {
headers: {
'Content-Type': response.headers.get('Content-Type') || 'application/octet-stream',
},
});
}Crypto API
Crypto API
Hashing
哈希计算
typescript
async function sha256(data: string): Promise<string> {
const encoder = new TextEncoder();
const dataBuffer = encoder.encode(data);
const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}typescript
async function sha256(data: string): Promise<string> {
const encoder = new TextEncoder();
const dataBuffer = encoder.encode(data);
const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}HMAC Signing
HMAC签名
typescript
async function signHMAC(key: string, data: string): Promise<string> {
const encoder = new TextEncoder();
const keyData = encoder.encode(key);
const dataBuffer = encoder.encode(data);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const signature = await crypto.subtle.sign('HMAC', cryptoKey, dataBuffer);
return btoa(String.fromCharCode(...new Uint8Array(signature)));
}typescript
async function signHMAC(key: string, data: string): Promise<string> {
const encoder = new TextEncoder();
const keyData = encoder.encode(key);
const dataBuffer = encoder.encode(data);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const signature = await crypto.subtle.sign('HMAC', cryptoKey, dataBuffer);
return btoa(String.fromCharCode(...new Uint8Array(signature)));
}Cache API
Cache API
typescript
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const cache = caches.default;
const cacheKey = new Request(request.url, { method: 'GET' });
// Check cache
let response = await cache.match(cacheKey);
if (response) {
return response;
}
// Fetch and cache
response = await fetch(request);
response = new Response(response.body, response);
response.headers.set('Cache-Control', 'public, max-age=3600');
// Store in cache (don't await)
ctx.waitUntil(cache.put(cacheKey, response.clone()));
return response;
}
};typescript
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const cache = caches.default;
const cacheKey = new Request(request.url, { method: 'GET' });
// 检查缓存
let response = await cache.match(cacheKey);
if (response) {
return response;
}
// 拉取数据并缓存
response = await fetch(request);
response = new Response(response.body, response);
response.headers.set('Cache-Control', 'public, max-age=3600');
// 存入缓存(无需等待执行完成)
ctx.waitUntil(cache.put(cacheKey, response.clone()));
return response;
}
};WebSockets (Durable Objects)
WebSockets(Durable Objects)
typescript
// Durable Object with WebSocket hibernation
export class WebSocketRoom {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const upgradeHeader = request.headers.get('Upgrade');
if (upgradeHeader !== 'websocket') {
return new Response('Expected websocket', { status: 426 });
}
const pair = new WebSocketPair();
const [client, server] = Object.values(pair);
// Accept with hibernation
this.state.acceptWebSocket(server);
return new Response(null, { status: 101, webSocket: client });
}
async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
// Handle incoming message
const data = typeof message === 'string' ? message : new TextDecoder().decode(message);
// Broadcast to all connected clients
for (const client of this.state.getWebSockets()) {
client.send(data);
}
}
async webSocketClose(ws: WebSocket, code: number, reason: string) {
ws.close(code, reason);
}
}typescript
// 支持WebSocket休眠的Durable Object
export class WebSocketRoom {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const upgradeHeader = request.headers.get('Upgrade');
if (upgradeHeader !== 'websocket') {
return new Response('Expected websocket', { status: 426 });
}
const pair = new WebSocketPair();
const [client, server] = Object.values(pair);
// 接受连接并启用休眠
this.state.acceptWebSocket(server);
return new Response(null, { status: 101, webSocket: client });
}
async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
// 处理 incoming 消息
const data = typeof message === 'string' ? message : new TextDecoder().decode(message);
// 广播给所有连接的客户端
for (const client of this.state.getWebSockets()) {
client.send(data);
}
}
async webSocketClose(ws: WebSocket, code: number, reason: string) {
ws.close(code, reason);
}
}When to Load References
何时加载对应参考文档
Load specific references based on the task:
- Making HTTP requests? → Load for timeout, retry, proxy patterns
references/fetch-api.md - Processing large data? → Load for TransformStream, chunking
references/streams-api.md - Encryption/signing? → Load for AES, RSA, JWT verification
references/crypto-api.md - Caching responses? → Load for Cache API patterns, TTL strategies
references/cache-api.md - Real-time features? → Load for WebSocket patterns, Durable Objects
references/websockets.md - Text encoding? → Load for TextEncoder, Base64, Unicode
references/encoding-api.md
根据任务需求加载特定参考文档:
- 需要发起HTTP请求? → 加载获取超时、重试、代理模式
references/fetch-api.md - 需要处理大数据? → 加载获取TransformStream、分块处理相关内容
references/streams-api.md - 需要加密/签名? → 加载获取AES、RSA、JWT验证相关内容
references/crypto-api.md - 需要缓存响应? → 加载获取Cache API模式、TTL策略相关内容
references/cache-api.md - 需要实现实时功能? → 加载获取WebSocket模式、Durable Objects相关内容
references/websockets.md - 需要处理文本编码? → 加载获取TextEncoder、Base64、Unicode相关内容
references/encoding-api.md
Templates
模板
| Template | Purpose | Use When |
|---|---|---|
| HTTP request utilities | Building API clients |
| Stream transformation | Processing large files |
| Crypto utilities | Signing, hashing, encryption |
| WebSocket DO | Real-time applications |
| 模板路径 | 用途 | 适用场景 |
|---|---|---|
| HTTP请求工具 | 构建API客户端 |
| 流转换工具 | 处理大文件 |
| 加密工具 | 签名、哈希计算、加密 |
| WebSocket DO实现 | 实时应用开发 |
Resources
资源
- Runtime APIs: https://developers.cloudflare.com/workers/runtime-apis/
- Fetch API: https://developers.cloudflare.com/workers/runtime-apis/fetch/
- Streams API: https://developers.cloudflare.com/workers/runtime-apis/streams/
- Web Crypto: https://developers.cloudflare.com/workers/runtime-apis/web-crypto/
- Cache API: https://developers.cloudflare.com/workers/runtime-apis/cache/
- WebSockets: https://developers.cloudflare.com/workers/runtime-apis/websockets/
- 运行时API:https://developers.cloudflare.com/workers/runtime-apis/
- Fetch API:https://developers.cloudflare.com/workers/runtime-apis/fetch/
- Streams API:https://developers.cloudflare.com/workers/runtime-apis/streams/
- Web Crypto:https://developers.cloudflare.com/workers/runtime-apis/web-crypto/
- Cache API:https://developers.cloudflare.com/workers/runtime-apis/cache/
- WebSockets:https://developers.cloudflare.com/workers/runtime-apis/websockets/