はじめに
Cloudflare Image Transformations を使うと、画像のリサイズやフォーマット変換を行えます。
ところが、外部ストレージの画像を変換しようとしたところ、404エラーで思ったよりも時間を使ってしまいました。この記事では実際にハマった流れを追いながら、最終的にどう解決したかを紹介します。
Transformationsの有効化方法
- Cloudflareダッシュボードにログインする
- Images > Transformationsに移動する
- 対象ゾーンのTransformationsを有効化する
画像最適化最初のアプローチ
GCSに保存した画像を変換しようとしたところ、次のエラーが返ってきました。
Cloudflare Images transformation failed: 404 - URL: https://images.example.com/cdn-cgi/image/...
やってみたこと&学び
1. クエリパラメータで指定 → 404
// ❌ 失敗例:クエリパラメータ形式
const transformationUrl =
`https://images.example.com/cdn-cgi/image?url=${imageUrl}&width=500&quality=80`
2. パスパラメータに修正 → 404
// ⚠️ 外部 URL だとうまくいかない例
const transformationUrl =
`https://images.example.com/cdn-cgi/image/width=500,quality=80/${imageUrl}`
内部リソースなら OK ですが、外部 URL だと 404 のまま…。
3. 最終解決策:cf.image
オプション ✅
Cloudflare Workersから fetch
するときに、cf.image
オプションを渡す方法が公式でも推奨されています。
const optimizeWithCloudflareImages = async (
imageUrl: string,
width?: number,
quality?: number,
format?: string,
): Promise<Response | null> => {
try {
// 必要ならフォーマットを変換
const imageFormat = (
format && ['avif', 'webp', 'json', 'jpeg', 'png'].includes(format)
? format
: undefined
) as 'avif' | 'webp' | 'json' | 'jpeg' | 'png' | undefined;
const response = await fetch(imageUrl, {
cf: {
cacheEverything: true,
cacheTtl: 60 * 60 * 24 * 365,
image: {
width,
quality,
fit: 'scale-down',
format: imageFormat,
metadata: 'none',
},
},
});
if (!response.ok) {
console.error(`画像の最適化に失敗しました (${imageUrl})`);
return null;
}
return response;
} catch (err) {
return null;
}
};
cf.image
を使うと、Cloudflare の内部リサイズエンジンが「同一ゾーン内リクエスト」として画像を扱わずに処理してくれます。そのため外部 URL でも 404 になりません。