Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Cloudflare で訪問者向けコンテンツを配信する

最終更新 Markdown で表示Agent セットアップ

コンテンツネゴシエーションとは、1 つの URL からリソースの異なる版を返し、エンドユーザー向けに体験を合わせる手法です。よくある例は、特定言語での配信(Accept-Language)、デバイス向けの最適化(User-Agent)、新しい画像形式の配信(Accept)です。

Cloudflare のグローバルネットワークは、この処理を大規模に扱う設計です。次世代画像の配信など一般的なケースでは、専用機能でネゴシエーションを簡素化できます。より独自のロジックが必要な場合は、Transform Rules、Snippets、Custom Cache Keys、Workers といったツールキットで細かく制御し、毎回適切なコンテンツを各ユーザーへ届けます。


クエリ文字列を使う

訪問者の所在地に応じてコンテンツを返すなど、区別できる URL を作れる場合は、Transform Rule の方法が適しています。

地理位置情報の例

この例では、e コマースサイトを運営しており、訪問者の国に応じて現地通貨で価格を表示します。

  1. Cloudflare ダッシュボードで、Rules の Overview ページを開きます。

    Overview を開く ↗
  2. Create rule を選択し、URL Rewrite Rule を選びます。

  3. Vary by Country - Canada など、分かりやすい名前を入力します。

  4. If incoming requests match...Custom filter expression を選択します。

  5. When incoming requests match... の下で、次の式を作成します。

    • Field: Country
    • Operator: equals
    • Value: Canada
  6. Then... の下で

    • PathPreserve を選択します。
    • QueryRewrite to: Dynamic loc=ca を選択します。
  7. Save を選択します。

これで、カナダからの /products/item へのリクエストは、オリジンまたはキャッシュに到達する前に /products/item?loc=ca に変換され、別のキャッシュエントリが作られます。


Vary for Images

Vary for Images は、オリジンが対応しているバリアントを Cloudflare に伝えます。Cloudflare は各版を別々にキャッシュし、毎回オリジンへ問い合わせずに、ブラウザーへ正しい版を返します。この機能は Cloudflare API で管理します。

Vary for Images を有効にする

この機能を有効にするには、API で variants ルール を作成します。このルールは、ファイル拡張子を、オリジンが返せる画像形式に対応付けます。

たとえば、次の API 呼び出しは、.jpeg.jpg ファイルについて、オリジンが image/webpimage/avif のバリアントを返せることを Cloudflare に伝えます。

Required API token permissions

At least one of the following token permissions is required:
  • Zone Settings Write
  • Zone Write
Change variants settingbash
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/variants" \
	--request PATCH \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"value": {
				"jpeg": [
						"image/webp",
						"image/avif"
				],
				"jpg": [
						"image/webp",
						"image/avif"
				]
		}
	}'

ルール作成後、Cloudflare は各画像バリアント用に別のキャッシュエントリを作り、新しいブラウザーを使う訪問者のパフォーマンスが向上します。

プログラムでキャッシュする(Snippets)

Snippets は、Cloudflare を通るリクエストに対してエッジで動く、自己完結した JavaScript の fetch ハンドラーです。キャッシュキーとレスポンスの振る舞いをプログラムで制御でき、ユーザーに見える URL は変えません。

例: A/B テスト

この例では、ab-test という名前の Cookie(値は group-a または group-b)で A/B テストを制御します。グループごとにページの別版をキャッシュします。

  1. Cloudflare ダッシュボードで Snippets ページを開きます。

    Snippets を開く ↗
  2. Create new Snippet を選択し、名前を ab-test-caching にします。

  3. 次のコードを貼り付けます。ab-test Cookie に基づいてキャッシュキーを変え、レスポンスを 30 日間キャッシュします。

const CACHE_DURATION = 30 * 24 * 60 * 60; // 30 days

export default {
  async fetch(request) {
    // Construct a new URL for the cache key based on the A/B cookie
    const abCookie = request.headers.get('Cookie')?.match(/ab-test=([^;]+)/)?.[1] || 'control';
    const url = new URL(request.url);
    url.pathname = `/ab-test/${abCookie}${url.pathname}`;

    const cacheKey = new Request(url, request);
    const cache = caches.default;

    let response = await cache.match(cacheKey);
    if (!response) {
      // If not in cache, fetch from origin
      response = await fetch(request);
      response = new Response(response.body, response);
      response.headers.set("Cache-Control", `s-maxage=${CACHE_DURATION}`);
      // Put the response into cache with the custom key
      await cache.put(cacheKey, response.clone());
    }
    return response;
  },
};
  1. Snippet を保存してデプロイします。
  2. Snippets ダッシュボードから Attach to routes を選択し、Snippet を割り当てます。

Custom Cache Keys(Enterprise)

アカウントが Enterprise プランの場合、Custom Cache Keys 機能で、キャッシュキーに含めるリクエスト属性をノーコードの画面から定義できます。

Custom Cache Key のオプション:

  • デバイスタイプでキャッシュする
  • クエリ文字列オプション No query string parameters except
  • ヘッダーと値を含める
  • Cookie 名と値を含める
  • ユーザー: デバイスタイプ、国、言語

例: 同じ URL、異なるコンテンツ

オリジンが同じ URL で、Accept ヘッダーに応じて異なるコンテンツタイプ(例: application/jsontext/html)を返す場合は、Custom Cache Key を使って別々にキャッシュします。

  1. Cloudflare ダッシュボードで Cache Rules ページを開きます。

    Cache Rules を開く ↗
  2. Create rule を選択します。

  3. Vary by Accept Header など、ルール名を入力します。

  4. ルールを適用する条件を設定します(特定のホスト名やパスなど)。

  5. Cache key の下で Use custom key を選択します。

  6. Add new を選択します。

    • Type: Header
    • Name: Accept
    • Value: 各 value を追加するか、すべて対象にする場合は空のままにします。
  7. Deploy を選択します。

この設定は、Accept ヘッダーの値に応じて別のキャッシュエントリを作り、API のコンテンツネゴシエーションに従います。

高度なロジックには Cloudflare Workers を使う

複雑なキャッシュのシナリオでは、Cloudflare Workers が、規模に応じた独自ロジック向けのフルなサーバーレス環境になります。

例: デバイスタイプ — Free / Pro / Business(Tiered Cache なし)

この Worker は、訪問者がモバイルかデスクトップかを判定し、それぞれ別のキャッシュエントリを作ります。正しいサイト版を配信し、キャッシュできます。

export default {
  async fetch(request, env, ctx) {
    const userAgent = request.headers.get('User-Agent') || '';
    const deviceType = userAgent.includes('Mobile') ? 'mobile' : 'desktop';

    // Create a new URL for the cache key that includes the device type
    const url = new URL(request.url);
    url.pathname = `/${deviceType}${url.pathname}`;

    const cacheKey = new Request(url, request);
    const cache = caches.default;

    let response = await cache.match(cacheKey);

    if (!response) {
      console.log(`Cache miss for ${deviceType} device. Fetching from origin.`);
      response = await fetch(request);
      let responseToCache = response.clone();
      ctx.waitUntil(cache.put(cacheKey, responseToCache));
    }

    return response;
  },
};

例: デバイスタイプ — Enterprise(Tiered Cache あり)

この Worker は、訪問者がモバイルかデスクトップかを判定し、それぞれ別のキャッシュエントリを作ります。正しいサイト版を配信し、キャッシュできます。Enterprise の cf.customCacheKey 機能を使います。

export default {
  async fetch(request) {
    // 1. Determine the device type from the User-Agent header
    const userAgent = request.headers.get('User-Agent') || '';
    const deviceType = userAgent.includes('Mobile') ? 'mobile' : 'desktop';

    // 2. Create a custom cache key by appending the device type to the URL
    const customCacheKey = `${request.url}-${deviceType}`;

    // 3. Fetch the response. Cloudflare's cache automatically uses the
    //    customCacheKey for cache operations (match, put).
    const response = await fetch(request, {
      cf: {
        cacheKey: customCacheKey,
      },
    });

    // Optionally, you can modify the response before returning it
    // For example, add a header to indicate which cache key was used
    const newResponse = new Response(response.body, response);
    newResponse.headers.set("X-Cache-Key", customCacheKey);
    return newResponse;
  },
};

例: Next.js の RSC ペイロードをキャッシュする

よくある課題は、Next.js のようなフレームワークからのコンテンツをキャッシュすることです。Next.js は同じ URL に対して、HTML のページ読み込みと RSC データペイロードを区別するために RSC(React Server Components)リクエストヘッダーを使います。次の方法が適しています。

方法 1: Transform Rules

いちばん簡単な方法は、RSC ヘッダーを確認して一意のクエリパラメーターをリクエストに付ける Transform Rule を作ることです。キャッシュ可能な URL が 2 つできます。HTML 用の /page と、RSC ペイロード用の /page?_rsc=1 です。

  1. Cloudflare ダッシュボードで、Rules の Overview ページを開きます。

    Overview を開く ↗
  2. Create rule を選択し、URL Rewrite Rule を選びます。

  3. Vary by RSC Header など、名前を入力します。

  4. If incoming requests matchCustom filter expression を選択します。

  5. When incoming requests match の下で、式を手動編集し、RSC ヘッダーの有無を確認します。

    • has_key(http.request.headers, "rsc")
  6. Then の下で:

    • PathPreserve を選択します。
    • QueryRewrite to を選び、Static: _rsc=1 を選択します。
  7. Save を選択します。

方法 2: Snippets または Custom Cache Keys

別の方法として、Snippets または Custom Cache Keys を使い、見える URL は変えずに RSC ヘッダーをキャッシュキーへ直接追加します。URL はすっきりしますが、設定はより高度になります。

役に立ちましたか?