跳到主要内容

Workers

Cloudflare Workers 是一个无服务器计算平台,允许你在全球边缘网络运行 JavaScript/TypeScript 代码。Workers 可以用于构建 API、处理请求、实现边缘计算等场景。

Workers 简介

什么是 Workers?

Workers 让你能够在 Cloudflare 的全球边缘节点运行代码,而不是在中心服务器。这意味着代码在离用户最近的地方执行,延迟极低。

用户请求 → Cloudflare 边缘节点 → Workers 执行 → 响应
(全球 300+ 城市)

Workers 的优势

零冷启动:基于 V8 Isolate 技术,启动时间几乎为 0ms,不像传统 Lambda 函数有冷启动延迟。

全球部署:代码自动部署到全球所有边缘节点,无需配置。

按需计费:只收取实际 CPU 执行时间,I/O 等待时间不计费。

免费额度:每天 10 万次请求,适合个人项目和小型应用。

技术规格

指标免费版付费版
CPU 时间10ms30s(可配置到 5 分钟)
内存128MB128MB
代码大小1MB10MB
请求数10 万次/天1000 万次/月($5)

支持的语言

  • JavaScript
  • TypeScript
  • Rust(编译为 WebAssembly)
  • C++(编译为 WebAssembly)
  • Python(通过 Pyodide)
  • Go(通过 TinyGo)

快速开始

安装 Wrangler

Wrangler 是 Cloudflare 的 CLI 工具,用于开发和部署 Workers:

npm install -g wrangler

登录认证

wrangler login

这会打开浏览器,授权 Wrangler 访问你的 Cloudflare 账户。

创建项目

npm create cloudflare@latest my-worker

按提示选择:

  • 项目类型:Hello World
  • 语言:TypeScript 或 JavaScript
  • 是否使用 Git:根据需要选择

项目结构

my-worker/
├── src/
│ └── index.ts # Worker 入口文件
├── wrangler.toml # 配置文件
├── package.json
└── tsconfig.json

本地开发

npx wrangler dev

访问 http://localhost:8787 查看效果。

部署

npx wrangler deploy

部署成功后会返回 Worker 的 URL,类似 https://my-worker.username.workers.dev

Worker 代码结构

基本结构

export default {
async fetch(request, env, ctx) {
return new Response('Hello World!');
},
};

参数说明

request:Request 对象,包含请求信息:

const url = new URL(request.url);
const method = request.method;
const headers = request.headers;
const body = await request.text();

env:环境变量和绑定:

const apiKey = env.API_KEY;
const value = await env.MY_KV.get('key');

ctx:执行上下文:

ctx.waitUntil(someAsyncTask());

处理不同请求方法

export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);

if (request.method === 'GET') {
return handleGet(url);
}

if (request.method === 'POST') {
const body = await request.json();
return handlePost(body);
}

return new Response('Method Not Allowed', { status: 405 });
},
};

返回 JSON 响应

return Response.json({
message: 'Hello',
data: { id: 1, name: 'Test' }
});

返回 HTML

return new Response(`
<!DOCTYPE html>
<html>
<head><title>My Worker</title></head>
<body><h1>Hello World</h1></body>
</html>
`, {
headers: { 'Content-Type': 'text/html' }
});

路由处理

简单路由

export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const path = url.pathname;

if (path === '/') {
return new Response('Home');
}

if (path === '/api/users') {
return Response.json({ users: [] });
}

if (path.startsWith('/api/posts/')) {
const id = path.split('/')[3];
return Response.json({ id, title: 'Post ' + id });
}

return new Response('Not Found', { status: 404 });
},
};

使用 Hono 框架

Hono 是一个轻量级 Web 框架,适合 Workers:

npm install hono
import { Hono } from 'hono';

const app = new Hono();

app.get('/', (c) => {
return c.text('Hello Hono!');
});

app.get('/api/users/:id', (c) => {
const id = c.req.param('id');
return c.json({ id, name: 'User ' + id });
});

app.post('/api/users', async (c) => {
const body = await c.req.json();
return c.json({ created: body }, 201);
});

export default app;

环境变量

配置环境变量

wrangler.toml 中配置:

name = "my-worker"
main = "src/index.ts"

[vars]
API_KEY = "your-api-key"
ENVIRONMENT = "production"

使用环境变量

export default {
async fetch(request, env, ctx) {
const apiKey = env.API_KEY;
const environment = env.ENVIRONMENT;

return Response.json({ apiKey, environment });
},
};

敏感信息(Secrets)

对于敏感信息,使用 Secrets:

wrangler secret put API_SECRET

输入值后,Secret 会被加密存储,不会出现在代码中。

绑定服务

KV 绑定

[[kv_namespaces]]
binding = "MY_KV"
id = "your-kv-namespace-id"
await env.MY_KV.put('key', 'value');
const value = await env.MY_KV.get('key');

R2 绑定

[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"
await env.MY_BUCKET.put('file.txt', fileContent);
const object = await env.MY_BUCKET.get('file.txt');

D1 绑定

[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "your-database-id"
const result = await env.DB.prepare(
'SELECT * FROM users WHERE id = ?'
).bind(1).first();

fetch API

Workers 可以发起 HTTP 请求:

基本请求

const response = await fetch('https://api.example.com/data');
const data = await response.json();

带参数请求

const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + env.API_KEY
},
body: JSON.stringify({
name: 'John',
email: '[email protected]'
})
});

并发请求

const [users, posts] = await Promise.all([
fetch('https://api.example.com/users').then(r => r.json()),
fetch('https://api.example.com/posts').then(r => r.json())
]);

定时任务(Cron Triggers)

配置定时任务

wrangler.toml 中配置:

[triggers]
crons = ["0 * * * *"] # 每小时执行

处理定时任务

export default {
async fetch(request, env, ctx) {
return new Response('Hello');
},

async scheduled(event, env, ctx) {
console.log('Cron trigger fired at:', new Date(event.scheduledTime));
await doSomething(env);
},
};

Cron 表达式示例

表达式说明
* * * * *每分钟
0 * * * *每小时
0 0 * * *每天午夜
0 0 * * 1每周一
0 0 1 * *每月 1 号

实战示例

API 代理

export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const apiUrl = 'https://api.example.com' + url.pathname;

const response = await fetch(apiUrl, {
method: request.method,
headers: {
'Authorization': 'Bearer ' + env.API_KEY,
'Content-Type': 'application/json'
},
body: request.body
});

return response;
},
};

缓存代理

export default {
async fetch(request, env, ctx) {
const cacheKey = new Request(request.url, request);
const cache = caches.default;

let response = await cache.match(cacheKey);
if (response) {
return response;
}

response = await fetch(request);
ctx.waitUntil(cache.put(cacheKey, response.clone()));

return response;
},
};

图片处理

export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const imageUrl = url.searchParams.get('url');
const width = url.searchParams.get('w') || '300';

const imageResponse = await fetch(imageUrl);
const imageBuffer = await imageResponse.arrayBuffer();

return new Response(imageBuffer, {
headers: {
'Content-Type': imageResponse.headers.get('Content-Type'),
'Cache-Control': 'public, max-age=31536000'
}
});
},
};

调试与日志

本地调试

npx wrangler dev

使用 console.log 输出调试信息。

查看日志

wrangler tail

实时查看 Worker 的日志输出。

日志示例

export default {
async fetch(request, env, ctx) {
console.log('Request URL:', request.url);
console.log('Request Method:', request.method);

const response = new Response('Hello');
console.log('Response Status:', response.status);

return response;
},
};

配置文件详解

wrangler.toml

name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
account_id = "your-account-id"

[vars]
ENVIRONMENT = "production"

[triggers]
crons = ["0 * * * *"]

[[kv_namespaces]]
binding = "MY_KV"
id = "your-kv-id"

[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "your-db-id"

[observability]
enabled = true

常见问题

Worker 超时怎么办?

免费版 CPU 时间限制 10ms,如果超时:

  1. 优化代码减少计算量
  2. 升级到付费版获得更长 CPU 时间
  3. 将耗时操作异步化

如何调试生产环境?

使用 wrangler tail 实时查看日志,或在代码中使用 console.log

如何处理 CORS?

const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
};

export default {
async fetch(request, env, ctx) {
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}

return new Response('Hello', { headers: corsHeaders });
},
};

参考链接

下一步

完成 Workers 学习后,接下来学习 Pages,了解如何部署静态网站。