名称: workers-runtime-apis
描述: Cloudflare Workers 运行时API,包括Fetch、Streams、Crypto、Cache、WebSockets和Encoding。用于HTTP请求、流处理、加密、缓存、实时连接,或处理API兼容性、响应处理、流处理错误。
Cloudflare Workers 运行时API
掌握Workers运行时API:Fetch、Streams、Crypto、Cache、WebSockets和文本编码。
快速参考
| API |
用途 |
常见使用场景 |
| Fetch |
HTTP请求 |
外部API、代理 |
| Streams |
数据流处理 |
大文件、实时处理 |
| Crypto |
密码学 |
哈希、签名、加密 |
| Cache |
响应缓存 |
性能优化 |
| WebSockets |
实时连接 |
聊天、实时更新 |
| Encoding |
文本编码 |
UTF-8、Base64 |
快速开始:Fetch API
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);
}
};
关键规则
- 始终为外部请求设置超时 - Workers有30秒限制,外部API可能挂起
- 在读取正文前克隆响应 - 正文只能读取一次
- 使用流处理大负载 - 不要将整个响应缓冲在内存中
- 缓存外部API响应 - 减少延迟和API成本
- 在try/catch中处理Crypto操作 - 无效输入会抛出错误
- WebSocket休眠以节省成本 - 使用带休眠的Durable Objects
前10个错误预防
| 错误 |
症状 |
预防措施 |
| 正文已读取 |
TypeError: Body has already been consumed |
读取前克隆响应 |
| Fetch超时 |
请求挂起,worker超时 |
使用AbortController设置超时 |
| 无效JSON |
SyntaxError: Unexpected token |
解析前检查content-type |
| 流已锁定 |
TypeError: ReadableStream is locked |
不要多次读取流 |
| Crypto密钥错误 |
DOMException: Invalid keyData |
验证密钥格式和算法 |
| 缓存未命中 |
返回undefined而非响应 |
返回前检查缓存 |
| WebSocket关闭 |
连接意外断开 |
处理关闭事件,实现重连 |
| 编码错误 |
TypeError: Invalid code point |
正确使用TextEncoder/TextDecoder |
| CORS被阻止 |
浏览器拒绝响应 |
添加适当的CORS头 |
| 请求大小 |
413 Request Entity Too Large |
流式处理大上传 |
Fetch API模式
带超时
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);
}
}
带重试
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('超过最大重试次数');
}
Streams API
转换流
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);
流式大响应
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
哈希
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签名
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
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');
// 存储到缓存(不await)
ctx.waitUntil(cache.put(cacheKey, response.clone()));
return response;
}
};
WebSockets(Durable Objects)
// 带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('期望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) {
// 处理传入消息
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);
}
}
何时加载参考
根据任务加载特定参考:
- 进行HTTP请求? → 加载
references/fetch-api.md获取超时、重试、代理模式
- 处理大数据? → 加载
references/streams-api.md获取TransformStream、分块
- 加密/签名? → 加载
references/crypto-api.md获取AES、RSA、JWT验证
- 缓存响应? → 加载
references/cache-api.md获取Cache API模式、TTL策略
- 实时功能? → 加载
references/websockets.md获取WebSocket模式、Durable Objects
- 文本编码? → 加载
references/encoding-api.md获取TextEncoder、Base64、Unicode
模板
| 模板 |
用途 |
使用时机 |
templates/fetch-patterns.ts |
HTTP请求实用程序 |
构建API客户端 |
templates/stream-processing.ts |
流转换 |
处理大文件 |
templates/crypto-operations.ts |
Crypto实用程序 |
签名、哈希、加密 |
templates/websocket-handler.ts |
WebSocket DO |
实时应用程序 |
资源