コンテンツにスキップ

フェッチを使用したキャッシュ

リソースをキャッシュする方法を、TTL、カスタムキャッシュキー、およびフェッチリクエストのキャッシュヘッダーを設定することで決定します。

export default {
async fetch(request) {
const url = new URL(request.url);
// キャッシュキーにはパスのみを使用し、クエリ文字列を削除します
// そして常にHTTPSを使用して保存します。例えば、https://www.example.com/file-uri-here
const someCustomKey = `https://${url.hostname}${url.pathname}`;
let response = await fetch(request, {
cf: {
// コンテンツタイプに関係なく、このフェッチを常にキャッシュします
// リソースを再検証する前に最大5秒間
cacheTtl: 5,
cacheEverything: true,
// エンタープライズ専用機能、他のプランについてはCache APIを参照してください
cacheKey: someCustomKey,
},
});
// Responseオブジェクトを再構築して、そのヘッダーを変更可能にします。
response = new Response(response.body, response);
// ブラウザで25分間キャッシュするためにキャッシュコントロールヘッダーを設定します
response.headers.set("Cache-Control", "max-age=1500");
return response;
},
};

HTMLリソースのキャッシング

// Cloudflareにアセットをキャッシュさせる
fetch(event.request, { cf: { cacheEverything: true } });

キャッシュレベルをCache Everythingに設定すると、アセットのデフォルトのキャッシュ可能性が上書きされます。TTLについては、Cloudflareは依然としてオリジンによって設定されたヘッダーに依存します。

カスタムキャッシュキー

リクエストのキャッシュキーは、キャッシュ目的で2つのリクエストが同じかどうかを決定します。リクエストが以前のリクエストと同じキャッシュキーを持っている場合、Cloudflareは両方に対して同じキャッシュされたレスポンスを提供できます。キャッシュキーの詳細については、カスタムキャッシュキーの作成ドキュメントを参照してください。

// このリクエストのキャッシュキーを"some-string"に設定します。
fetch(event.request, { cf: { cacheKey: "some-string" } });

通常、CloudflareはリクエストのURLに基づいてキャッシュキーを計算します。ただし、時には異なるURLをキャッシュ目的で同じように扱いたい場合があります。たとえば、ウェブサイトのコンテンツがAmazon S3とGoogle Cloud Storageの両方からホストされている場合、両方の場所に同じコンテンツがあり、Workerを使用してランダムにバランスを取ることができます。しかし、コンテンツの2つのコピーをキャッシュしたくはありません。カスタムキャッシュキーを利用して、サブリクエストURLではなく元のリクエストURLに基づいてキャッシュすることができます。

export default {
async fetch(request) {
let url = new URL(request.url);
if (Math.random() < 0.5) {
url.hostname = "example.s3.amazonaws.com";
} else {
url.hostname = "example.storage.googleapis.com";
}
let newRequest = new Request(url, request);
return fetch(newRequest, {
cf: { cacheKey: request.url },
});
},
};

異なるゾーンを代表して動作するWorkersは、お互いのキャッシュに影響を与えることはできません。キャッシュキーを上書きできるのは、自分のゾーン内でリクエストを行うときのみです(上記の例ではevent.request.urlが保存されたキーでした)、またはCloudflareにないホストへのリクエストです。別のCloudflareゾーン(たとえば、別のCloudflare顧客に属する)へのリクエストを行うと、そのゾーンはCloudflare内で自分のコンテンツがどのようにキャッシュされるかを完全に制御します。上書きすることはできません。

オリジンのレスポンスコードに基づく上書き

// 200ステータスコードの場合、86400秒間レスポンスをキャッシュさせる
// 404の場合は1秒、500エラーはキャッシュしない。
fetch(request, {
cf: { cacheTtlByStatus: { "200-299": 86400, 404: 1, "500-599": 0 } },
});

このオプションは、レスポンスのステータスコードに基づいてTTLを選択し、cacheEverything: trueを自動的に設定しないcacheTtl機能のバージョンです。このリクエストに対するレスポンスが一致するステータスコードを持っている場合、Cloudflareは指示された時間だけキャッシュし、オリジンから送信されたキャッシュディレクティブを上書きします。cacheTtl機能の詳細については、リクエストページの詳細を確認できます。

リクエストファイルタイプに基づくキャッシュ動作のカスタマイズ

カスタムキャッシュキーとレスポンスコードに基づく上書きを使用して、オリジンからのレスポンスステータスコードとリクエストファイルタイプに基づいてTTLを設定するWorkerを書くことができます。

以下の例は、ストリーミングメディアアセットのリクエストをキャッシュするためにこれを使用する方法を示しています:

index.js
export default {
async fetch(request) {
// 新しいURLをインスタンス化して変更可能にします
const newRequest = new URL(request.url);
const customCacheKey = `${newRequest.hostname}${newRequest.pathname}`;
const queryCacheKey = `${newRequest.hostname}${newRequest.pathname}${newRequest.search}`;
// 異なるアセットタイプは通常、異なるキャッシング戦略を持ちます。ほとんどの場合、ユーザー生成コンテンツでないオーディオ、ビデオ、画像などのメディアコンテンツは、頻繁に更新する必要がないため、長いTTLが最適です。しかし、HLSストリーミングでは、マニフェストファイルは通常短いTTLに設定されているため、再生に影響を与えないようにします。これらのファイルには、プレーヤーが必要とするデータが含まれています。アセットタイプのカテゴリごとにキャッシング戦略をオブジェクト内の配列に設定することで、アプリケーションのメディアコンテンツに関する複雑なニーズを解決できます。
const cacheAssets = [
{
asset: "video",
key: customCacheKey,
regex:
/(.*\/Video)|(.*\.(m4s|mp4|ts|avi|mpeg|mpg|mkv|bin|webm|vob|flv|m2ts|mts|3gp|m4v|wmv|qt))/,
info: 0,
ok: 31556952,
redirects: 30,
clientError: 10,
serverError: 0,
},
{
asset: "image",
key: queryCacheKey,
regex:
/(.*\/Images)|(.*\.(jpg|jpeg|png|bmp|pict|tif|tiff|webp|gif|heif|exif|bat|bpg|ppm|pgn|pbm|pnm))/,
info: 0,
ok: 3600,
redirects: 30,
clientError: 10,
serverError: 0,
},
{
asset: "frontEnd",
key: queryCacheKey,
regex: /^.*\.(css|js)/,
info: 0,
ok: 3600,
redirects: 30,
clientError: 10,
serverError: 0,
},
{
asset: "audio",
key: customCacheKey,
regex:
/(.*\/Audio)|(.*\.(flac|aac|mp3|alac|aiff|wav|ogg|aiff|opus|ape|wma|3gp))/,
info: 0,
ok: 31556952,
redirects: 30,
clientError: 10,
serverError: 0,
},
{
asset: "directPlay",
key: customCacheKey,
regex: /.*(\/Download)/,
info: 0,
ok: 31556952,
redirects: 30,
clientError: 10,
serverError: 0,
},
{
asset: "manifest",
key: customCacheKey,
regex: /^.*\.(m3u8|mpd)/,
info: 0,
ok: 3,
redirects: 2,
clientError: 1,
serverError: 0,
},
];
const { asset, regex, ...cache } =
cacheAssets.find(({ regex }) => newRequest.pathname.match(regex)) ?? {};
const newResponse = await fetch(request, {
cf: {
cacheKey: cache.key,
polish: false,
cacheEverything: true,
cacheTtlByStatus: {
"100-199": cache.info,
"200-299": cache.ok,
"300-399": cache.redirects,
"400-499": cache.clientError,
"500-599": cache.serverError,
},
cacheTags: ["static"],
},
});
const response = new Response(newResponse.body, newResponse);
// デバッグ目的のため
response.headers.set("debug", JSON.stringify(cache));
return response;
},
};