关于 cloudflare-images
cloudflare-images 是 Cloudflare Images 的操作指南,面向需要存储、投放和处理图像的开发者。内容涵盖 Images API、图像转换及变体,并说明公开图像和私有图像的处理方式。
主要功能
- 01上传文件或导入外部图像
- 02为用户生成直接上传链接
- 03转换图像尺寸、格式和效果
- 04管理命名及灵活变体
- 05使用签名 URL 投放私有图像
适用场景
- 01将外部图像迁移到 Cloudflare Images
- 02让用户在不暴露 API 密钥的情况下上传
- 03按设备尺寸提供响应式图像
- 04通过限时链接分享私有图像
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill cloudflare-images安装后在 Claude Code 中输入/cloudflare-images确认已加载。
附带文件README.mdSKILL.json
详细介绍
Cloudflare Images
状态:已投入生产 ✅ 最后更新:2025-10-26 依赖项:已启用 Images 的 Cloudflare 账户 最新版本:Cloudflare Images API v2
概述
Cloudflare Images 提供两项强大的功能:
- Images API:上传、存储和提供图像,并自动进行优化和生成变体
- 图像转换:调整任意公开可访问图像的大小、优化图像并进行转换
主要优势:
- 通过全球 CDN 分发
- 自动转换为 WebP/AVIF 格式
- 适用于不同场景的变体(最多 100 个)
- 创作者直接上传(用户上传时无需 API 密钥)
- 用于私有图像的签名 URL
- 通过 URL 或 Workers 转换任意图像
快速开始(5 分钟)
1. 启用 Cloudflare Images
登录 Cloudflare 控制面板 → Images → 为你的账户启用。
获取你的 Account ID,并创建具有 Cloudflare Images: Edit 权限的 API 令牌。
重要原因:
- 所有 API 操作都需要 Account ID 和 API 令牌
- Images 免费套餐包含有限次数的转换
2. 上传你的第一张图像
curl --request POST \
--url https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/images/v1 \
--header 'Authorization: Bearer <API_TOKEN>' \
--header 'Content-Type: multipart/form-data' \
--form 'file=@./image.jpg'
响应包含:
id:用于提供图像的图像 IDvariants:提供图像的 URL 数组
重要:
- 使用
multipart/form-data编码(而非application/json) - 图像 ID 会自动生成(也可使用自定义 ID)
3. 提供图像
<img src="https://imagedelivery.net/<ACCOUNT_HASH>/<IMAGE_ID>/public" />
默认的 public 变体用于提供图像。替换为你自己的变体名称。
4. 启用图像转换
控制面板 → Images → Transformations → 选择你的区域 → Enable for zone
现在你可以转换任意图像:
<img src="/cdn-cgi/image/width=800,quality=85/uploads/photo.jpg" />
重要原因:
- 适用于存储在 Cloudflare Images 之外的图像
- 在 Cloudflare 的全球网络上自动缓存
- 无需额外的存储费用
5. 通过 Workers 转换(高级)
export default {
async fetch(request: Request): Promise<Response> {
const imageURL = "https://example.com/image.jpg";
return fetch(imageURL, {
cf: {
image: {
width: 800,
quality: 85,
format: "auto" // WebP/AVIF for supporting browsers
}
}
});
}
};
三项功能系统
功能 1:Images API(上传与存储)
将图像存储在 Cloudflare 网络上,并在全球范围内提供。
上传方式:
- 文件上传 - 直接从你的服务器上传文件
- 通过 URL 上传 - 从外部 URL 导入图像
- 创作者直接上传 - 为用户上传生成一次性上传 URL
提供方式:
- 默认域名:
imagedelivery.net - 自定义域名:
/cdn-cgi/imagedelivery/... - 签名 URL:带有过期令牌的私有图像
参见:templates/upload-api-basic.ts、templates/direct-creator-upload-backend.ts
功能 2:图像转换
优化和调整任意图像(存储在 Images 中或外部)。
两种方式:
- URL 转换 - 特殊 URL 格式
- Workers 转换 - 通过 fetch 进行程序化控制
常见转换:
- 调整大小:
width=800,height=600,fit=cover - 优化:
quality=85,format=auto - 效果:
blur=10,sharpen=3 - 裁剪:
gravity=face,zoom=0.5
参见:templates/transform-via-url.ts、templates/transform-via-workers.ts
功能 3:变体
为不同使用场景预定义图像尺寸。
命名变体(最多 100 个):
- 创建一次,随处使用
- 示例:
thumbnail、avatar、hero - 转换效果一致
灵活变体(动态):
- 按账户启用
- 在 URL 中使用转换参数
- 示例:
w=400,sharpen=3 - 不能与签名 URL 配合使用
参见:templates/variants-management.ts、references/variants-guide.md
Images API - 上传方式
方式 1:文件上传(基础)
curl --request POST \
https://api.cloudflare.com/client/v4/accounts/{account_id}/images/v1 \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: multipart/form-data" \
--form 'file=@./image.jpg' \
--form 'requireSignedURLs=false' \
--form 'metadata={"key":"value"}'
关键选项:
file:图像文件(必需)id:自定义 ID(可选,默认自动生成)requireSignedURLs:私有图像设为true(默认:false)metadata:JSON 对象(最大 1024 字节,终端用户不可见)
响应:
{
"result": {
"id": "2cdc28f0-017a-49c4-9ed7-87056c83901",
"filename": "image.jpg",
"uploaded": "2022-01-31T16:39:28.458Z",
"requireSignedURLs": false,
"variants": [
"https://imagedelivery.net/Vi7wi5KSItxGFsWRG2Us6Q/2cdc28f0.../public"
]
}
}
参见:templates/upload-api-basic.ts
方法 2:通过 URL 上传
无需先下载,即可从外部来源导入图片。
curl --request POST \
https://api.cloudflare.com/client/v4/accounts/{account_id}/images/v1 \
--header "Authorization: Bearer <API_TOKEN>" \
--form 'url=https://example.com/image.jpg' \
--form 'metadata={"source":"external"}'
适用场景:
- 从其他服务迁移图片
- 导入用户提供的 URL
- 备份外部来源的图片
重要提示:
- URL 必须可公开访问,或需要通过身份验证
- 支持 HTTP 基本身份验证:
https://user:[email protected]/image.jpg - 同一请求中不能同时使用
file和url
参见:templates/upload-via-url.ts
方法 3:创建者直接上传 ⭐
生成一次性上传 URL,让用户直接上传到 Cloudflare(无需暴露 API 密钥)。
后端端点(生成上传 URL):
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: true,
metadata: { userId: '12345' },
expiry: '2025-10-26T18:00:00Z' // Optional: default 30min, max 6hr
})
}
);
const { uploadURL, id } = await response.json();
// Return uploadURL to frontend
前端上传(HTML + JavaScript):
<form id="upload-form">
<input type="file" id="file-input" accept="image/*" />
<button type="submit">Upload</button>
</form>
<script>
document.getElementById('upload-form').addEventListener('submit', async (e) => {
e.preventDefault();
const fileInput = document.getElementById('file-input');
const formData = new FormData();
formData.append('file', fileInput.files[0]); // MUST be named 'file'
const uploadURL = 'UPLOAD_URL_FROM_BACKEND'; // Get from backend
const response = await fetch(uploadURL, {
method: 'POST',
body: formData // NO Content-Type header, browser sets multipart/form-data
});
if (response.ok) {
console.log('Upload successful!');
}
});
</script>
重要原因:
- 不会向浏览器暴露 API 密钥
- 用户直接上传到 Cloudflare(速度更快,无需中间服务器)
- 一次性 URL 在使用后或超时后失效
- 可通过 Webhook 接收上传成功或失败通知
关键 CORS 修复:
- ✅ 应当:使用
multipart/form-data编码(由浏览器设置标头) - ✅ 应当:将字段命名为
file(而不是image或其他名称) - ✅ 应当:仅从后端调用
/direct_uploadAPI - ❌ 不要:设置
Content-Type: application/json或image/jpeg - ❌ 不要:从浏览器调用
/direct_upload(CORS 会失败)
参见:templates/direct-creator-upload-backend.ts、templates/direct-creator-upload-frontend.html、references/direct-upload-complete-workflow.md
图片转换
URL 转换
使用特殊 URL 格式转换图片。
URL 格式:
https://<ZONE>/cdn-cgi/image/<OPTIONS>/<SOURCE-IMAGE>
示例:
<img src="/cdn-cgi/image/width=800,quality=85,format=auto/uploads/photo.jpg" />
常用选项:
- 尺寸:
width=800、height=600、fit=cover - 质量:
quality=85(1-100) - 格式:
format=auto(自动检测 WebP/AVIF)、format=webp、format=jpeg - 裁剪:
gravity=auto(智能裁剪)、gravity=face、trim=10 - 效果:
blur=10、sharpen=3、brightness=1.2、contrast=1.1 - 旋转:
rotate=90、flip=h(水平翻转)、flip=v(垂直翻转)
适配选项:
scale-down:缩小以适配(不会放大)contain:调整大小以适配尺寸(保持宽高比)cover:调整大小以填满尺寸(可能会裁剪)crop:裁剪至指定尺寸pad:调整大小并添加内边距(与background选项搭配使用)
格式自动检测:
<img src="/cdn-cgi/image/format=auto/image.jpg" />
Cloudflare 会提供:
- 向支持 AVIF 的浏览器(Chrome、Edge)提供 AVIF
- 向不支持 AVIF 的浏览器(Safari、Firefox)提供 WebP
- 以原始格式(JPEG)作为后备格式
参见:templates/transform-via-url.ts、references/transformation-options.md
Workers 转换
使用自定义 URL 方案以编程方式转换图片。
基本模式:
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
// Custom URL scheme: /images/thumbnail/photo.jpg
if (url.pathname.startsWith('/images/thumbnail/')) {
const imagePath = url.pathname.replace('/images/thumbnail/', '');
const imageURL = `https://storage.example.com/${imagePath}`;
return fetch(imageURL, {
cf: {
image: {
width: 300,
height: 300,
fit: 'cover',
quality: 85
}
}
});
}
return new Response('Not found', { status: 404 });
}
};
进阶:内容协商:
const accept = request.headers.get('accept') || '';
let format: 'avif' | 'webp' | 'auto' = 'auto';
if (/image\/avif/.test(accept)) {
format = 'avif';
} else if (/image\/webp/.test(accept)) {
format = 'webp';
}
return fetch(imageURL, {
cf: {
image: {
format,
width: 800,
quality: 85
}
}
});
Workers 转换的优势:
- 自定义 URL 方案:隐藏图片存储位置
- 预设名称:使用
thumbnail、avatar、large代替像素值 - 内容协商:根据浏览器提供最合适的格式
- 访问控制:提供图片前检查身份验证
- 动态调整尺寸:根据设备类型计算尺寸
参见:templates/transform-via-workers.ts、references/transformation-options.md
变体管理
命名变体(最多 100 个)
为不同使用场景创建预定义转换。
通过 API 创建:
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/images/v1/variants" \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
"id": "avatar",
"options": {
"fit": "cover",
"width": 200,
"height": 200,
"metadata": "none"
},
"neverRequireSignedURLs": false
}'
在 URL 中使用:
<img src="https://imagedelivery.net/<ACCOUNT_HASH>/<IMAGE_ID>/avatar" />
适用场景:
- 在应用中保持图片尺寸一致
- 私有图片(可与签名 URL 配合使用)
- 简单且可预测的 URL
参见:templates/variants-management.ts
灵活变体
使用 URL 中的参数进行动态转换。
启用(每个账户仅需一次):
curl --request PATCH \
https://api.cloudflare.com/client/v4/accounts/{account_id}/images/v1/config \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{"flexible_variants": true}'
在 URL 中使用:
<img src="https://imagedelivery.net/<ACCOUNT_HASH>/<IMAGE_ID>/w=400,sharpen=3" />
适用场景:
- 需要动态调整尺寸
- 仅适用于公开图片(不能与签名 URL 配合使用)
- 快速原型设计
重要提示:
- ❌ 不能与
requireSignedURLs=true搭配使用 - ✅ 私有图片请使用命名变体
参见:references/variants-guide.md
签名 URL(私有图片)
使用 HMAC-SHA256 令牌为私有图片生成有时效限制的 URL。
URL 格式:
https://imagedelivery.net/<ACCOUNT_HASH>/<IMAGE_ID>/<VARIANT>?exp=<EXPIRY>&sig=<SIGNATURE>
生成签名(Workers 示例):
async function generateSignedURL(
imageId: string,
variant: string,
expirySeconds: number = 3600
): Promise<string> {
const accountHash = 'YOUR_ACCOUNT_HASH';
const signingKey = 'YOUR_SIGNING_KEY'; // Dashboard → Images → Keys
const expiry = Math.floor(Date.now() / 1000) + expirySeconds;
const stringToSign = `${imageId}${variant}${expiry}`;
const encoder = new TextEncoder();
const keyData = encoder.encode(signingKey);
const messageData = encoder.encode(stringToSign);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageData);
const sig = Array.from(new Uint8Array(signature))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
return `https://imagedelivery.net/${accountHash}/${imageId}/${variant}?exp=${expiry}&sig=${sig}`;
}
用法:
const signedURL = await generateSignedURL('image-id', 'public', 3600);
// Returns URL valid for 1 hour
适用场景:
- 用户个人资料照片(分享前为私有)
- 付费内容(限时访问)
- 临时下载
- 安全的图片交付
参见:templates/signed-urls-generation.ts、references/signed-urls-guide.md
响应式图片
为不同屏幕尺寸提供最佳图片尺寸。
使用命名变体:
<img
srcset="
https://imagedelivery.net/<HASH>/<ID>/mobile 480w,
https://imagedelivery.net/<HASH>/<ID>/tablet 768w,
https://imagedelivery.net/<HASH>/<ID>/desktop 1920w
"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1920px"
src="https://imagedelivery.net/<HASH>/<ID>/desktop"
alt="Responsive image"
/>
使用灵活变体:
<img
srcset="
https://imagedelivery.net/<HASH>/<ID>/w=480,f=auto 480w,
https://imagedelivery.net/<HASH>/<ID>/w=768,f=auto 768w,
https://imagedelivery.net/<HASH>/<ID>/w=1920,f=auto 1920w
"
sizes="(max-width: 480px) 480px, (max-width: 768px) 768px, 1920px"
src="https://imagedelivery.net/<HASH>/<ID>/w=1920,f=auto"
alt="Responsive image"
/>
艺术指导(移动设备与桌面设备使用不同裁剪方式):
<picture>
<source
media="(max-width: 767px)"
srcset="https://imagedelivery.net/<HASH>/<ID>/mobile-square"
/>
<source
media="(min-width: 768px)"
srcset="https://imagedelivery.net/<HASH>/<ID>/desktop-wide"
/>
<img src="https://imagedelivery.net/<HASH>/<ID>/desktop-wide" alt="Hero image" />
</picture>
参见:templates/responsive-images-srcset.html、references/responsive-images-patterns.md
关键规则
务必遵循
✅ Direct Creator Upload 使用 multipart/form-data
✅ 将文件字段命名为 file(而不是 image 或其他名称)
✅ 仅从后端调用 /direct_upload API(不要从浏览器调用)
✅ 转换时使用 HTTPS URL(不支持 HTTP)
✅ 对图片路径中的特殊字符进行 URL 编码
✅ 使用 /cdn-cgi/image/ 前,先在 zone 上启用转换
✅ 私有图片使用命名变体(签名 URL)
✅ 检查 Cf-Resized 标头以确认是否存在转换错误
✅ 设置 format=auto 以自动转换为 WebP/AVIF
✅ 使用 fit=scale-down 以防止不必要的放大
切勿执行
❌ 文件上传时使用 application/json Content-Type
❌ 从浏览器调用 /direct_upload(CORS 会失败)
❌ 在 requireSignedURLs=true 时使用灵活变体
❌ 调整 SVG 文件大小(它们本身即可缩放)
❌ 转换时使用 HTTP URL(仅支持 HTTPS)
❌ 在 URL 中使用空格或未转义的 Unicode 字符
❌ 在 Workers 中多次转换同一张图片(会导致 9403 循环)
❌ 图片大小超过 100 megapixels
❌ 在 Workers 中使用 /cdn-cgi/image/ 端点(改用 cf.image)
❌ 忘记在使用前于 zone 上启用转换
已知问题预防
此技能可预防 13+ 个已记录的问题。
问题 #1:Direct Creator Upload CORS 错误
错误:Access to XMLHttpRequest blocked by CORS policy: Request header field content-type is not allowed
来源:Cloudflare Community #345739、#368114
原因:服务器的 CORS 设置仅允许 Content-Type 标头使用 multipart/form-data
预防措施:
// ✅ CORRECT
const formData = new FormData();
formData.append('file', fileInput.files[0]);
await fetch(uploadURL, {
method: 'POST',
body: formData // Browser sets multipart/form-data automatically
});
// ❌ WRONG
await fetch(uploadURL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }, // CORS error
body: JSON.stringify({ file: base64Image })
});
问题 #2:错误 5408 - 上传超时
错误:上传约 15 秒后出现 Error 5408
来源:Cloudflare Community #571336
原因:Cloudflare 的请求超时时间为 30 秒;上传速度慢或文件过大都会超出限制
预防措施:
- 上传前压缩图片(使用 Canvas API 在客户端压缩)
- 设置合理的文件大小限制(例如,最大 10MB)
- 向用户显示上传进度
- 妥善处理超时错误
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
if (file.size > MAX_FILE_SIZE) {
alert('File too large. Please select an image under 10MB.');
return;
}
问题 #3:错误 400 - 文件参数无效
错误:400 Bad Request,且错误消息没有提供有用信息
来源:Cloudflare Community #487629
原因:文件字段必须命名为 file(而不是 image、photo 等)
预防措施:
// ✅ CORRECT
formData.append('file', imageFile);
// ❌ WRONG
formData.append('image', imageFile); // 400 error
formData.append('photo', imageFile); // 400 error
问题 #4:CORS 预检失败
错误:预检 OPTIONS 请求被阻止
来源:Cloudflare Community #306805
原因:直接从浏览器调用 /direct_upload API(该操作应仅在后端进行)
预防措施:
ARCHITECTURE:
Browser → Backend API → POST /direct_upload → Returns uploadURL → Browser uploads to uploadURL
切勿向浏览器公开 API 令牌。在后端生成上传 URL,再返回给前端。
问题 #5:错误 9401 - 参数无效
错误:Cf-Resized: err=9401 - 必需的 cf.image 选项缺失或无效
来源:Cloudflare Images 文档 - 故障排除
原因:缺少必需的转换参数或参数值无效
预防:
// ✅ CORRECT
fetch(imageURL, {
cf: {
image: {
width: 800,
quality: 85,
format: 'auto'
}
}
});
// ❌ WRONG
fetch(imageURL, {
cf: {
image: {
width: 'large', // Must be number
quality: 150 // Max 100
}
}
});
问题 #6:错误 9402 - 图像过大
错误:Cf-Resized: err=9402 - 图像过大或连接中断
来源:Cloudflare Images 文档 - 故障排除
原因:图像超过最大面积(100 百万像素)或下载失败
预防:
- 转换前验证图像尺寸
- 使用尺寸合理的源图像(最大 10000x10000px)
- 妥善处理网络错误
问题 #7:错误 9403 - 请求循环
错误:Cf-Resized: err=9403 - Worker 正在获取自己的 URL 或已调整尺寸的图像
来源:Cloudflare Images 文档 - 故障排除
原因:对已转换的图像再次应用转换,或 Worker 获取自身
预防:
// ✅ CORRECT
if (url.pathname.startsWith('/images/')) {
const originalPath = url.pathname.replace('/images/', '');
const originURL = `https://storage.example.com/${originalPath}`;
return fetch(originURL, { cf: { image: { width: 800 } } });
}
// ❌ WRONG
if (url.pathname.startsWith('/images/')) {
// Fetches worker's own URL, causes loop
return fetch(request, { cf: { image: { width: 800 } } });
}
问题 #8:错误 9406/9419 - URL 格式无效
错误:Cf-Resized: err=9406 或 err=9419 - URL 不是 HTTPS,或 URL 中包含空格/未转义的 Unicode 字符
来源:Cloudflare Images 文档 - 故障排除
原因:图像 URL 使用 HTTP(而非 HTTPS)或包含无效字符
预防:
// ✅ CORRECT
const imageURL = "https://example.com/images/photo%20name.jpg";
// ❌ WRONG
const imageURL = "http://example.com/images/photo.jpg"; // HTTP not allowed
const imageURL = "https://example.com/images/photo name.jpg"; // Space not encoded
URL 路径务必使用 encodeURIComponent():
const filename = "photo name.jpg";
const imageURL = `https://example.com/images/${encodeURIComponent(filename)}`;
问题 #9:错误 9412 - 响应不是图像
错误:Cf-Resized: err=9412 - 源站返回了 HTML,而非图像
来源:Cloudflare Images 文档 - 故障排除
原因:源站服务器返回了 404 页面或错误页面(HTML),而非图像
预防:
// Verify URL before transforming
const originResponse = await fetch(imageURL, { method: 'HEAD' });
const contentType = originResponse.headers.get('content-type');
if (!contentType?.startsWith('image/')) {
return new Response('Not an image', { status: 400 });
}
return fetch(imageURL, { cf: { image: { width: 800 } } });
问题 #10:超过图像最大面积限制(错误 9413)
错误:Cf-Resized: err=9413 - 图像超过 100 百万像素
来源:Cloudflare Images 文档 - 故障排除
原因:源图像尺寸超过 100 百万像素(例如,10000x10000px)
预防:
- 上传前验证图像尺寸
- 预处理过大的图像
- 拒绝超过阈值的图像
const MAX_MEGAPIXELS = 100;
if (width * height > MAX_MEGAPIXELS * 1_000_000) {
return new Response('Image too large', { status: 413 });
}
问题 #11:灵活变体与签名 URL 不兼容
错误:灵活变体无法用于私有图像
来源:Cloudflare Images 文档 - 启用灵活变体
原因:requireSignedURLs=true 时无法使用灵活变体
预防:
// ✅ CORRECT - Use named variants for private images
await uploadImage({
file: imageFile,
requireSignedURLs: true // Use named variants: /public, /avatar, etc.
});
// ❌ WRONG - Flexible variants don't support signed URLs
// Cannot use: /w=400,sharpen=3 with requireSignedURLs=true
问题 #12:SVG 缩放限制
错误:无法通过转换调整 SVG 文件的尺寸
来源:Cloudflare Images 文档 - SVG 文件
原因:SVG 本身可缩放(矢量格式),不适用尺寸调整
预防:
// SVGs can be served but not resized
// Use any variant name as placeholder
// https://imagedelivery.net/<HASH>/<SVG_ID>/public
// SVG will be served at original size regardless of variant settings
问题 #13:默认会剥除 EXIF 元数据
错误:上传的 JPEG 中的 GPS 数据和相机设置被移除
来源:Cloudflare Images 文档 - 通过 URL 转换
原因:默认行为会剥除所有元数据,版权信息除外
预防:
// Preserve metadata
fetch(imageURL, {
cf: {
image: {
width: 800,
metadata: 'keep' // Options: 'none', 'copyright', 'keep'
}
}
});
选项:
none:剥除所有元数据copyright:仅保留版权标签(JPEG 默认值)keep:保留大部分 EXIF 元数据,包括 GPS
使用捆绑资源
模板(templates/)
可直接复制粘贴的常见模式代码:
- wrangler-images-binding.jsonc - Wrangler 配置(无需绑定)
- upload-api-basic.ts - 将文件上传到 Images API
- upload-via-url.ts - 从外部 URL 导入图像
- direct-creator-upload-backend.ts - 生成一次性上传 URL
- direct-creator-upload-frontend.html - 用户上传表单
- transform-via-url.ts - URL 转换示例
- transform-via-workers.ts - Workers 转换模式
- variants-management.ts - 创建、列出和删除变体
- signed-urls-generation.ts - HMAC-SHA256 签名 URL 生成
- responsive-images-srcset.html - 响应式图像模式
- batch-upload.ts - 面向高容量上传的 Batch API
用法:
cp templates/upload-api-basic.ts src/upload.ts
# Edit with your account ID and API token
参考资料(references/)
Claude 可按需加载的深入文档:
- api-reference.md - 完整的 API 端点(上传、列出、删除、变体)
- transformation-options.md - 所有转换参数及示例
- variants-guide.md - 命名变体与灵活变体,以及各自的适用场景
- signed-urls-guide.md - HMAC-SHA256 实现细节
- direct-upload-complete-workflow.md - 完整架构和流程
- responsive-images-patterns.md - srcset、sizes、艺术指导
- format-optimization.md - WebP/AVIF 自动转换策略
- top-errors.md - 13 种以上错误及详细故障排查说明
加载时机:
- 深入了解特定功能
- 排查复杂问题
- 了解 API 详情
- 实现高级模式
脚本(scripts/)
check-versions.sh - 验证 API 端点是否为最新版本
高级主题
自定义域名
使用您自己的域名提供图像,而不是使用 imagedelivery.net。
URL 格式:
https://example.com/cdn-cgi/imagedelivery/<ACCOUNT_HASH>/<IMAGE_ID>/<VARIANT>
要求:
- 域名必须托管在 Cloudflare 上(与 Images 属于同一账户)
- 必须通过 Cloudflare 代理(橙色云朵)
自定义路径(转换规则):
将 /images/... 重写为 /cdn-cgi/imagedelivery/...:
- Dashboard → Rules → Transform Rules → Rewrite URL
- 匹配:
starts_with(http.request.uri.path, "/images/") - 重写:
/cdn-cgi/imagedelivery/<ACCOUNT_HASH>${substring(http.request.uri.path, 7)}
现在,/images/{id}/{variant} → /cdn-cgi/imagedelivery/{hash}/{id}/{variant}
参见:通过自定义域名提供图像
Batch API
使用 Batch Token 进行高容量上传。
主机:batch.imagedelivery.net(而非 api.cloudflare.com)
用法:
# Create batch token in dashboard: Images → Batch API
curl "https://batch.imagedelivery.net/images/v1" \
--header "Authorization: Bearer <BATCH_TOKEN>" \
--form 'file=@./image.jpg'
适用场景:
- 迁移数千张图像
- 批量上传工作流
- 自动导入图像
参见:templates/batch-upload.ts
Webhook
接收上传成功或失败的通知(仅限 Direct Creator Upload)。
设置:
- Dashboard → Notifications → Destinations → Webhooks → Create
- 输入 Webhook URL 并进行测试
- Notifications → All Notifications → Add → Images → Select webhook
Payload(示例):
{
"imageId": "2cdc28f0-017a-49c4-9ed7-87056c83901",
"status": "uploaded",
"metadata": {"userId": "12345"}
}
适用场景:
- 上传后更新数据库
- 触发图像处理流水线
- 通知用户上传状态
参见:配置 Webhook
故障排查
问题:图像未转换
症状:/cdn-cgi/image/... 返回原始图像或 404
解决方案:
- 在区域上启用转换:Dashboard → Images → Transformations → Enable for zone
- 确认区域已通过 Cloudflare 代理(橙色云朵)
- 检查源图像是否可公开访问
- 等待 5–10 分钟,让设置生效
问题:直接上传返回 CORS 错误
症状:浏览器控制台中出现 Access-Control-Allow-Origin 错误
解决方案:
- 使用
multipart/form-data编码(让浏览器设置 Content-Type) - 不要从浏览器调用
/direct_upload;应从后端调用 - 将文件字段命名为
file(而不是image) - 移除手动设置的 Content-Type 标头
问题:Worker 转换返回 9403 循环错误
症状:响应标头中出现 Cf-Resized: err=9403
解决方案:
- 不要获取 Worker 自身的 URL(请使用外部源站)
- 不要转换已经调整过大小的图片
- 检查 URL 路由逻辑,避免循环
问题:签名 URL 无法使用
症状:访问签名 URL 时出现 403 Forbidden
解决方案:
- 确认上传图片时使用了
requireSignedURLs=true - 检查签名生成方式(HMAC-SHA256)
- 确保过期时间戳在未来
- 确认签名密钥与控制面板中的密钥一致(Images → Keys)
- 签名 URL 不能使用灵活变体(请使用命名变体)
问题:图片已上传但未显示
症状:上传返回 200 OK,但图片未显示在控制面板中
解决方案:
- 检查响应中是否包含
draft: true(Direct Creator Upload) - 等待上传完成(通过 GET
/images/v1/{id}检查) - 确认账户 ID 匹配
- 检查 Webhook 中是否有上传错误
完整设置清单
- 已启用 Images 的 Cloudflare 账户
- 已获取账户 ID 和 API 令牌(Images: Edit 权限)
- [ ](可选)已在区域上启用图片转换
- [ ](可选)已为常见用例创建变体
- [ ](可选)如需动态调整大小,已启用灵活变体
- [ ](可选)已获取私有图片的签名密钥
- [ ](可选)已配置上传通知的 Webhook
- [ ](可选)已通过 Transform Rules 配置自定义域名
- 已实现上传方式(文件、URL 或直接创建者上传)
- 已测试服务 URL(imagedelivery.net 或自定义域名)
- 已测试转换(URL 或 Workers)
- 已实现错误处理(CORS、超时、大小限制)
官方文档
- Cloudflare Images:https://developers.cloudflare.com/images/
- 开始使用:https://developers.cloudflare.com/images/get-started/
- 上传图片:https://developers.cloudflare.com/images/upload-images/
- Direct Creator Upload:https://developers.cloudflare.com/images/upload-images/direct-creator-upload/
- 转换图片:https://developers.cloudflare.com/images/transform-images/
- 通过 URL 转换:https://developers.cloudflare.com/images/transform-images/transform-via-url/
- 通过 Workers 转换:https://developers.cloudflare.com/images/transform-images/transform-via-workers/
- 创建变体:https://developers.cloudflare.com/images/manage-images/create-variants/
- 提供私有图片:https://developers.cloudflare.com/images/manage-images/serve-images/serve-private-images/
- 故障排除:https://developers.cloudflare.com/images/reference/troubleshooting/
- API 参考:https://developers.cloudflare.com/api/resources/images/
软件包版本(已于 2025-10-26 验证)
API 版本:v2(用于直接上传),v1(用于标准上传)
无需 npm 软件包——使用原生 Cloudflare API
可选:
@cloudflare/workers-types@latest——Workers 的 TypeScript 类型
有问题?遇到故障?
- 查看
references/top-errors.md了解常见问题 - 确认设置流程中的所有步骤均已完成
- 查看官方文档:https://developers.cloudflare.com/images/
- 确认已在区域上启用转换
- 确认 Direct Creator Upload 的 CORS 设置