You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于国家缓存SvelteKit站点的不同页面版本?

基于特定Cookie(country)缓存SvelteKit页面的解决方案

针对你的场景——仅基于country Cookie值区分缓存版本,而非所有Cookie,以下是几种可行的实现方案:

方案1:服务器端提取country值生成自定义缓存键

在SvelteKit的hooks.server.js中,手动解析Cookie获取country值,以此构建专属缓存键,实现精准的版本区分。这种方式完全由你控制缓存逻辑,不受其他Cookie影响。

示例代码:

// hooks.server.js
import { parse } from 'cookie';

// 小流量站点可用内存Map,大流量建议替换为Redis等分布式缓存
const pageCache = new Map();

export async function handle({ event, resolve }) {
  // 解析Cookie获取country,设置默认值(如US)
  const cookies = parse(event.request.headers.get('cookie') || '');
  const country = cookies.country || 'US';
  
  // 构建缓存键:路径+country值
  const cacheKey = `${event.url.pathname}-${country}`;
  
  // 检查缓存是否存在
  if (pageCache.has(cacheKey)) {
    return new Response(pageCache.get(cacheKey), {
      headers: { 'Cache-Control': 'public, max-age=3600' }
    });
  }
  
  // 无缓存则渲染页面
  const response = await resolve(event);
  const responseBody = await response.text();
  
  // 存入缓存
  pageCache.set(cacheKey, responseBody);
  
  // 设置缓存控制头
  response.headers.set('Cache-Control', 'public, max-age=3600');
  return response;
}

方案2:CDN层过滤Cookie并使用自定义Vary头

如果你使用Cloudflare、Netlify等CDN服务,可以在CDN层面提取country Cookie,转换为自定义请求头(如X-Country),然后将Vary头设置为该自定义头。这样CDN只会基于X-Country的值缓存不同版本,忽略其他Cookie变化。

以Cloudflare Workers为例,示例代码:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  let country = 'US';
  const cookies = request.headers.get('cookie');
  
  // 提取country Cookie值
  if (cookies) {
    const cookieEntries = cookies.split(';').map(item => item.trim().split('='));
    const countryCookie = cookieEntries.find(([key]) => key === 'country');
    if (countryCookie) country = countryCookie[1];
  }
  
  // 修改请求,添加自定义X-Country头
  const modifiedRequest = new Request(request, {
    headers: new Headers(request.headers)
  });
  modifiedRequest.headers.set('X-Country', country);
  
  // 转发请求并设置Vary头
  const response = await fetch(modifiedRequest);
  const modifiedResponse = new Response(response.body, response);
  modifiedResponse.headers.set('Vary', 'X-Country');
  
  return modifiedResponse;
}

在SvelteKit的load函数或钩子中,可通过event.request.headers.get('X-Country')获取地区值,再调用Shopify API返回对应内容。

方案3:将country嵌入URL路径/查询参数

把country值作为URL的一部分(如/us/products或/products?country=us),利用URL天然的唯一性作为缓存键。这种方式无需处理Cookie相关的缓存逻辑,缓存系统会自动区分不同版本。

示例实现(动态路由):

<!-- src/routes/[country]/+page.server.js -->
export async function load({ params }) {
  const country = params.country;
  // 调用Shopify Storefront API获取对应国家的商品价格
  const products = await fetch(`https://your-shopify-store.myshopify.com/api/2024-07/graphql.json`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Shopify-Storefront-Access-Token': 'your-token'
    },
    body: JSON.stringify({
      query: `
        query getProducts($country: CountryCode) {
          products(first: 10) {
            edges {
              node {
                title
                priceRange {
                  minVariantPrice {
                    amount
                    currencyCode
                  }
                }
              }
            }
          }
        }
      `,
      variables: { country: country.toUpperCase() }
    })
  }).then(res => res.json());
  
  return { products, country };
}

注:需要处理默认跳转逻辑——当用户访问无country的URL时,根据Cookie或IP重定向到对应地区的URL。


内容的提问来源于stack exchange,提问作者chromata31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:07:16