엣지에서의 지리적 라우팅: 콘텐츠 개인화 및 GDPR 규정 준수
국가, 지역, 언어를 기반으로 라우팅 논리를 구축하는 방법을 알아보세요. 지오펜싱, 현지화된 가격에 대한 예가 포함된 Workers에서 직접 메인 서버를 변경하지 않고 GDPR 준수.
지리적 라우팅이 엣지에 속하는 이유
지리적 위치를 기반으로 콘텐츠를 개인화하는 것은 글로벌 웹 애플리케이션의 가장 일반적인 요구사항: 현지 통화, 국가별 규정(유럽의 경우 GDPR, 캘리포니아의 CCPA), 특정 관할권의 콘텐츠를 차단하고 리디렉션합니다. 지역 도메인을 향해.
역사적으로 이는 서버 측 지리 위치 데이터베이스로 처리되었습니다. (MaxMind GeoLite2) 또는 수동으로 구성된 CDN 규칙을 사용합니다. 두 가지 접근 방식 모두 제한 사항이 있습니다. 데이터베이스 서버가 대기 시간을 추가하고 CDN 규칙은 정적입니다. 동적으로 업데이트하기가 어렵습니다.
Cloudflare Workers를 사용하면 지리적 위치가 이미 사용 가능
개체에 request.cf 유지 관리할 데이터베이스가 없습니다.
Cloudflare는 네트워크의 BGP 토폴로지를 기반으로 위치를 결정합니다.
IP 조회가 아니며 국가 수준 정확도가 99.9% 이상입니다.
무엇을 배울 것인가
- 다음에서 사용 가능한 속성
request.cf지리적 위치에 대한 - 지오펜싱: 국가별 차단 및 리디렉션
- 현지화된 가격: 지역에 따른 통화 및 VAT
- GDPR 준수: EU 사용자를 위한 자동 쿠키 동의
- 사용자 정의 헤더를 사용한 다중 지역 라우팅
- 배포 없이 지역 기반 논리 테스트
객체 request.cf Cloudflare 제공
Cloudflare 작업자에 대한 각 요청에는 제목이 포함됩니다. cf 와
Cloudflare가 실시간으로 결정하는 지리적 및 네트워크 메타데이터:
// Tutte le proprieta disponibili in request.cf
export default {
async fetch(request: Request): Promise<Response> {
const cf = request.cf as CfProperties;
// Geolocalizzazione
const country = cf.country; // "IT" - ISO 3166-1 alpha-2
const region = cf.region; // "Puglia" - nome della regione
const regionCode = cf.regionCode; // "75" - codice regione
const city = cf.city; // "Bari"
const postalCode = cf.postalCode; // "70121"
const latitude = cf.latitude; // "41.1171"
const longitude = cf.longitude; // "16.8719"
const timezone = cf.timezone; // "Europe/Rome"
const continent = cf.continent; // "EU"
// Rete
const asn = cf.asn; // 1234 - Autonomous System Number
const asOrganization = cf.asOrganization; // "Telecom Italia"
const isEuCountry = cf.isEUCountry; // "1" o "0"
// Performance
const colo = cf.colo; // "FCO" - datacenter Cloudflare piu vicino
const httpProtocol = cf.httpProtocol; // "HTTP/2"
const tlsVersion = cf.tlsVersion; // "TLSv1.3"
return Response.json({
country,
region,
city,
timezone,
continent,
isEuCountry,
colo,
});
},
};
// Tipo per le proprieta cf (parziale)
interface CfProperties {
country?: string;
region?: string;
regionCode?: string;
city?: string;
postalCode?: string;
latitude?: string;
longitude?: string;
timezone?: string;
continent?: string;
asn?: number;
asOrganization?: string;
isEUCountry?: string;
colo?: string;
httpProtocol?: string;
tlsVersion?: string;
}
지오펜싱: 국가별 차단
지오펜싱(Geo-fencing)은 콘텐츠를 특정 사이트로 차단하거나 리디렉션하는 패턴입니다. 국가. 가장 일반적인 사용 사례는 국제 제재를 위한 차단, 지역 라이선스(스트리밍, 미디어)가 있는 콘텐츠 및 아직 시장이 확보되지 않은 콘텐츠 특정 제품에 적용 가능:
// src/geo-fence-worker.ts
// Paesi con accesso bloccato (esempio: sanzioni, licenze)
const BLOCKED_COUNTRIES = new Set(['KP', 'IR', 'SY', 'CU']);
// Paesi che richiedono un redirect a una versione localizzata
const REDIRECTS: Record<string, string> = {
DE: 'https://de.example.com',
FR: 'https://fr.example.com',
JP: 'https://jp.example.com',
};
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const cf = request.cf as CfProperties;
const country = cf.country ?? 'US';
const url = new URL(request.url);
// Blocco per paesi non consentiti
if (BLOCKED_COUNTRIES.has(country)) {
return new Response(
JSON.stringify({
error: 'Service not available in your region',
country,
}),
{
status: 451, // 451 Unavailable For Legal Reasons
headers: {
'Content-Type': 'application/json',
'Vary': 'CF-IPCountry',
},
}
);
}
// Redirect verso versione localizzata per certi paesi
const redirectTarget = REDIRECTS[country];
if (redirectTarget && !url.pathname.startsWith('/api/')) {
const targetUrl = new URL(url.pathname + url.search, redirectTarget);
return Response.redirect(targetUrl.toString(), 302);
}
// Aggiunge header con il paese per il downstream (server di origine)
const headers = new Headers(request.headers);
headers.set('CF-Worker-Country', country);
headers.set('CF-Worker-Continent', cf.continent ?? '');
headers.set('CF-Worker-Timezone', cf.timezone ?? '');
// Prosegui verso il server di origine
return fetch(new Request(request.url, {
method: request.method,
headers,
body: ['GET', 'HEAD'].includes(request.method) ? undefined : request.body,
}));
},
};
interface CfProperties {
country?: string;
continent?: string;
timezone?: string;
}
interface Env {}
현지화된 가격 및 통화
고객의 현지 통화로 가격을 표시하는 것이 가장 좋습니다. 전환율을 높이는 전자상거래입니다. 작업자를 사용하면 다음을 수행할 수 있습니다. 요청이 도달하기 전에 올바른 통화를 결정합니다. 원본 서버:
// src/pricing-worker.ts - prezzi localizzati all'edge
interface CurrencyConfig {
code: string;
symbol: string;
position: 'before' | 'after';
vatRate: number; // IVA in percentuale (0.22 = 22%)
}
const COUNTRY_CURRENCY: Record<string, CurrencyConfig> = {
// Eurozona
IT: { code: 'EUR', symbol: '€', position: 'before', vatRate: 0.22 },
DE: { code: 'EUR', symbol: '€', position: 'before', vatRate: 0.19 },
FR: { code: 'EUR', symbol: '€', position: 'before', vatRate: 0.20 },
ES: { code: 'EUR', symbol: '€', position: 'before', vatRate: 0.21 },
// Altre valute
GB: { code: 'GBP', symbol: '£', position: 'before', vatRate: 0.20 },
US: { code: 'USD', symbol: '






