INTEGRITY Документация

Персонализация контента с Cloudflare

Content negotiation, то есть согласование содержимого, представляет собой практику отдачи разных версий ресурса по одному URL с учётом особенностей конкретного пользователя. Распространённые примеры включают отправку контента на определённом языке (Accept-Language), оптимизация под устройство (User-Agent), или отдача современных форматов изображений (Accept).

Глобальная сеть Cloudflare рассчитана на такие задачи в любом масштабе. Для типовых сценариев, например отдачи изображений нового поколения, эта задача упрощена благодаря отдельной функции. Для более гибкой логики Cloudflare предлагает набор инструментов, включая Transform Rules, Snippets, Custom Cache Keys и Workers, что даёт вам точный контроль над тем, какой контент получает каждый пользователь в любой момент.


Использование строк запроса

Transform Rule метод идеально подходит, когда вы можете создать отдельный URL, например для показа содержимого в зависимости от местоположения посетителя.

Пример геолокации

В этом примере вы управляете сайтом электронной коммерции и хотите показывать цены в местной валюте в зависимости от страны посетителя.

  1. В панели управления Cloudflare перейдите в раздел Rules Обзор страницу.

    Перейдите в Обзор ↗
  2. Выберите Создать правило и выберите опцию URL Rewrite Rule.

  3. Введите понятное имя, например Vary by Country - Canada.

  4. В Если входящие запросы соответствуют..., выберите Настраиваемое выражение фильтра.

  5. В разделе Когда входящие запросы совпадают..., создайте следующее выражение:

    • Поле: Country
    • Оператор: equals
    • Значение: Canada
  6. В разделе Затем...

    • для Путь, выберите Сохранить.
    • для Запрос, выберите Rewrite to: Динамический loc=ca
  7. Выберите Save.

Теперь запросы из Канады к /products/item будет преобразован в /products/item?loc=ca до того как запрос достигнет источника или кеша, создавая отдельную запись кеша.


Vary for Images

Vary for Images сообщает Cloudflare, какие варианты поддерживает ваш источник. После этого Cloudflare кеширует каждую версию отдельно и отдаёт браузерам нужную версию, не обращаясь каждый раз к источнику. Эта функция настраивается через Cloudflare API.

Включите Vary for Images

Чтобы включить эту функцию, создайте правило вариантов через API. Это правило сопоставляет расширения файлов с форматами изображений, которые может отдавать ваш источник.

Например, следующий вызов API сообщает Cloudflare, что для .jpeg и .jpg файлов ваш источник может отдавать image/webp и image/avif варианты:

Необходимые разрешения API-токена

Хотя бы одно из следующих права доступа токена требуется:
Изменение настройки вариантов
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 представляют собой самостоятельные обработчики fetch на JavaScript, которые выполняются на edge для ваших запросов через Cloudflare. Они позволяют программно взаимодействовать с кешем и дают полный контроль над cache key и поведением ответа, не меняя URL, который видит пользователь.

Пример: A/B-тестирование

В этом примере вы проводите A/B-тестирование, управляемое файлом cookie с именем ab-test (со значениями group-a или group-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 выберите Привязать к маршрутам чтобы назначить Snippet.

Custom Cache Keys (Enterprise)

Если ваш аккаунт использует тариф Enterprise, Custom Cache Keys функция предоставляет интерфейс без написания кода для определения того, какие свойства запроса включаются в ключ кеша.

Параметры Custom Cache Key:

Пример: одинаковый URL, разное содержимое

Если ваш источник отдаёт разные типы контента (например, application/json и text/html) по одному и тому же URL на основе Accept заголовка используйте пользовательский ключ кэша, чтобы кэшировать их отдельно.

  1. На панели управления Cloudflare перейдите к разделу Cache Rules страницу.

    Перейдите в Cache Rules ↗
  2. Выберите Создать правило.

  3. Введите название правила, например Vary by Accept Header.

  4. Задайте условие применения правила (например, конкретный хост или путь).

  5. В разделе Ключ кеша, выберите Использование пользовательского ключа.

  6. Выберите Добавить.

    • Тип: Header
    • Название: Accept
    • Значение: добавляйте каждый value, или оставьте пустым для всех.
  7. Выберите Развернуть.

Эта конфигурация создаёт отдельные записи кеша на основе Accept значение заголовка с учётом согласования содержимого (content negotiation) вашего API.

Использование Cloudflare Workers для расширенной логики

Для сложных сценариев кэширования Cloudflare Workers предоставляют полноценную бессерверную среду, идеально подходящую для собственной логики в большом масштабе.

Пример: тип устройства для Free/Pro/Biz (без 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;
  },
};

Пример: кеширование полезной нагрузки RSC в Next.js

Распространённая сложность заключается в кешировании контента из фреймворков, таких как Next.js, которые используют RSC (React Server Components) для различения загрузок HTML страниц и передачи данных RSC по одному и тому же URL. Вот лучшие способы работы с этим.

Способ 1: Transform Rules

Простейшее решение заключается в том, чтобы создать Transform Rule которое проверяет наличие RSC заголовок и добавляет к запросу уникальный параметр запроса, создавая два разных кешируемых URL-адреса: /page (для HTML) и /page?_rsc=1 (для полезной нагрузки RSC).

  1. В панели управления Cloudflare перейдите в раздел Rules Обзор страницу.

    Перейдите в Обзор ↗
  2. Выберите Создать правило и выберите опцию URL Rewrite Rule.

  3. Введите имя, например Vary by RSC Header.

  4. В Если входящие запросы соответствуют, выберите Настраиваемое выражение фильтра.

  5. В разделе Когда входящие запросы соответствуют, вручную отредактируйте выражение так, чтобы оно проверяло наличие RSC заголовок:

    • has_key(http.request.headers, "rsc")
  6. В разделе Затем:

    • Для Путь, выберите Сохранить.
    • Для Запрос, выберите Rewrite to, выберите Статический: _rsc=1.
  7. Выберите Save.

Способ 2: Snippets или Custom Cache Keys

Также можно использовать Snippets или Custom Cache Keys чтобы добавить RSC заголовок напрямую в ключ кеша без изменения видимого URL-адреса. Это делает URL-адрес чище, но требует более сложной настройки.