← Cloudflare Rules / rules / snippets
Kdy použít Snippets a kdy Workers
Tento návod vám pomůže určit, kdy použít Snippets a kdy Workers v globální síti Cloudflare. Obsahuje osvědčené postupy, srovnání a praktické případy použití, které vám pomohou vybrat pro vaši zátěž ten správný produkt.
Co jsou Snippets?
Cloudflare Snippets poskytují rychlý deklarativní způsob úpravy požadavků a odpovědí HTTP na edge, aniž byste potřebovali plnohodnotnou výpočetní platformu. Snippets rozšiřují Cloudflare Rules tím, že umožňuje napsat logiku založenou na JavaScriptu, která upravuje požadavky předtím, než dorazí na origin, a odpovědi poté, co se vrátí z upstreamu.
Snippets vám umožňují:
- Upravujte hlavičky, ověřujte JWT tokeny a implementujte složité přepisy nebo přesměrování.
- Opakujte neúspěšné požadavky na jiné origin servery a použijte vlastní strategie ukládání do mezipaměti.
- Postupné spouštění více Snippets, přičemž každý Snippet upraví požadavek nebo odpověď, než ji předá dalšímu.
Snippets jsou bez příplatku součástí všechny placené plány, díky čemuž jsou preferovaným řešením pro odlehčenou logiku na edge.
Co jsou Workers?
Naproti tomu Cloudflare Workers poskytují plnou výpočetní platformu určenou pro aplikace vyžadující stav, výpočetní výkon a integrace s produkty Cloudflare Developer Platform. Workers pracují na cenový model založený na využití a zahrnují bezplatnou úroveň.
Výběr správného produktu
Snippets se ideálně hodí pro rychlé a bezplatné úpravy požadavků a odpovědí na edge síti. Rozšiřují Cloudflare Rules bez nutnosti další infrastruktury nebo externích řešení.
Kdy použít Snippets
- Ultrarychlé úpravy provozu aplikované přímo v síti Cloudflare.
- Rozšiřte Cloudflare Rules nad rámec vestavěných akcí pro větší kontrolu.
- Zjednodušuje migraci CDN nahrazením VCL, EdgeWorkers nebo logiky provozované on-premise.
- Upravujte hlavičky, ukládejte odpovědi do mezipaměti a provádějte přesměrování.
- Integrujte edge logiku do vývojových workflow pomocí JavaScriptu.
K čemu Snippets nejsou určeny
- Trvalá správa stavu (například ukládání relací nebo databáze).
- Výpočetně náročné úlohy (například transformace obrázků nebo AI inference).
- Hluboké integrace s Developer Platform služby jako Durable Objects nebo D1.
- Případy použití vyžadující pokročilé funkce runtime, jako například:
Klíčové funkce
- Ultrarychlé provádění optimalizované pro edge, poháněné Ruleset Engine a Workers runtime.
- Zahrnuto bez příplatku u všechny placené plány.
- Podrobné porovnávání požadavků pomocí desítek atributů požadavku, například URI, user-agent, a soubory cookie.
- Sekvenční spouštění: více Snippets může běžet na stejný požadavek a provádět úpravy postupně, krok za krokem.
- Nativní integrace s Cloudflare Rules : Snippets přebírají úpravy požadavku z jiných produktů spuštěných v dřívějších fáze požadavku.
- Podpora JavaScriptu a Web API, včetně:
- Základní Workers runtime funkce, jako například:
- Automatizované nasazování a verzování prostřednictvím Terraform.
Snippets vs Workers: srovnání funkcí
| Funkce | Snippets | Workers |
|---|---|---|
| Spouštění skriptů na základě atributů požadavku (například hlaviček, geolokace a cookies) | ✅ | ❌ |
| Spouštění kódu na konkrétní trase URL | ✅ | ✅ |
| Upravte HTTP požadavky/odpovědi nebo doručte jiná odpověď | ✅ | ✅ |
| Přidat, odebrat, nebo přepsat hlavičky dynamicky | ✅ | ✅ |
| Cache prostředků na edge | ✅ | ✅ |
| Dynamické směrování provozu mezi origin servery | ✅ | ✅ |
| Ověřte se požadavky, předběžné podepsání adres URL spusťte A/B testování | ✅ | ✅ |
| Definujte logiku pomocí JavaScript a Web API | ✅ | ✅ |
| Provádět výpočetně náročné úlohy (například AI, transformace obrázků) | ❌ | ✅ |
| Ukládání trvalých dat (například KV, Durable Objects, a D1) | ❌ | ✅ |
| Vytvořte API a full-stack aplikace | ❌ | ✅ |
| Použijte TypeScript, Python, Rust nebo jiný programovací jazyky | ❌ | ✅ |
| Podpora ne-HTTP protokoly | ❌ | ✅ |
| Analýza spuštění protokoly a sledovat metriky výkonu | ❌ | ✅ |
| Nasazení přes rozhraní příkazové řádky (CLI) | ❌ | ✅ |
| Nasazujte postupně a vraťte se k předchozí verze | ❌ | ✅ |
| Optimalizujte spouštění pomocí Smart Placement | ❌ | ✅ |
Příklady kódu: šablony Common Snippets
Níže najdete praktické příklady použití, které demonstrují Snippets v praxi. Další šablony pro rychlý start najdete v Příklady sekce.
Úprava hlaviček HTTP
Dynamicky upravuje hlavičky požadavků a odpovědí.
export default {
async fetch(request) {
// Get the current timestamp
const timestamp = Date.now();
// Convert the timestamp to hexadecimal format
const hexTimestamp = timestamp.toString(16);
// Clone the request and add the custom header with HEX timestamp
const modifiedRequest = new Request(request, {
headers: new Headers(request.headers),
});
modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);
// Pass the modified request to the origin
const response = await fetch(modifiedRequest);
// Clone the response so that it's no longer immutable
const newResponse = new Response(response.body, response);
// Add a custom header with a value to the response
newResponse.headers.append(
"x-snippets-hello",
"Hello from Cloudflare Snippets",
);
// Delete headers from the response
newResponse.headers.delete("x-header-to-delete");
newResponse.headers.delete("x-header2-to-delete");
// Adjust the value for an existing header in the response
newResponse.headers.set("x-header-to-change", "NewValue");
// Serve modified response to the visitor
return newResponse;
},
};Zobrazení vlastní stránky údržby
Směruje provoz na stránku údržby, když váš origin prochází plánovanou údržbou.
export default {
async fetch(request) {
return new Response(
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>We'll Be Right Back!</title>
<style> body { font-family: Arial, sans-serif; text-align: center; padding: 20px; } </style>
</head>
<body>
<h1>We'll Be Right Back!</h1>
<p>Our site is undergoing maintenance. Check back soon!</p>
</body>
</html>
`,
{ status: 503, headers: { "Content-Type": "text/html" } },
);
},
};Vlastní cache
Provádí programové ukládání do mezipaměti na edge serverech a snižuje tak zátěž originu.
const CACHE_DURATION = 30 * 24 * 60 * 60; // 30 days
export default {
async fetch(request) {
const cache = caches.default;
const cacheKey = new Request(request.url, { method: "GET" });
let response = await cache.match(cacheKey);
if (!response) {
response = await fetch(request);
response = new Response(response.body, response);
response.headers.set("Cache-Control", `s-maxage=${CACHE_DURATION}`);
await cache.put(cacheKey, response.clone());
}
return response;
},
};Přesměrování na základě kódu země
Přesměrovává návštěvníky na základě jejich geografické polohy.
export default {
async fetch(request) {
const country = request.cf.country;
const redirectMap = {
US: "https://example.com/us",
EU: "https://example.com/eu",
};
if (redirectMap[country])
return Response.redirect(redirectMap[country], 301);
return fetch(request);
},
};Přesměrování 403 Forbidden na jinou stránku
Pokud origin server odpověděl s 403 Forbidden chybovém kódu přesměruje návštěvníka na jinou stránku.
export default {
async fetch(request) {
// Send original request to the origin
const response = await fetch(request);
// Check if origin responded with 403 status code
if (response.status == 403) {
// If so, redirect to this URL
const destinationURL = "https://example.com";
// With this status code
const statusCode = 301;
// Serve redirect
return Response.redirect(destinationURL, statusCode);
}
// Otherwise, serve origin's response
else {
return response;
}
},
};Opakování na jiném origin serveru
Pokud odpověď na původní požadavek není 200 OK nebo přesměrování odešle na jiný origin.
export default {
async fetch(request) {
// Send original request to the origin
const response = await fetch(request);
// If response is not 200 OK or a redirect, send to another origin
if (!response.ok && !response.redirected) {
// First, clone the original request to construct a new request
const newRequest = new Request(request);
// Add a header to identify a re-routed request at the new origin
newRequest.headers.set("X-Rerouted", "1");
// Clone the original URL
const url = new URL(request.url);
// Send request to a different origin / hostname
url.hostname = "example.com";
// Serve response to the new request from the origin
return await fetch(url, newRequest);
}
// If response is 200 OK or a redirect, serve it
return response;
},
};Odebrání polí z odpovědi API
Pokud origin server odpoví ve formátu JSON, před vrácením odpovědi návštěvníkovi odstraní citlivá pole.
export default {
async fetch(request) {
// Send original request to the origin
const response = await fetch(request);
// Check if origin responded with JSON
try {
// Parse API response as JSON
var api_response = response.json();
// Specify the fields you want to delete. For example, to delete "botManagement" array from parsed JSON:
delete api_response.botManagement;
// Serve modified API response
return Response.json(api_response);
} catch (err) {
// On failure, serve unmodified origin's response
return response;
}
},
};Nastavit hlavičky CORS
Upraví Cross-Origin Resource Sharing (CORS) ↗ hlavičky a zpracovává preflight požadavky.
// Define CORS headers
const corsHeaders = {
"Access-Control-Allow-Origin": "*", // Replace * with your allowed origin(s)
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", // Adjust allowed methods as needed
"Access-Control-Allow-Headers": "Content-Type, Authorization", // Adjust allowed headers as needed
"Access-Control-Max-Age": "86400", // Adjust max age (in seconds) as needed
};
export default {
async fetch(request) {
// Make a copy of the request to modify its headers
const modifiedRequest = new Request(request);
// Handle preflight requests (OPTIONS)
if (request.method === "OPTIONS") {
return new Response(null, {
headers: {
...corsHeaders,
},
status: 200, // Respond with OK status for preflight requests
});
}
// Pass the modified request through to the origin
const response = await fetch(modifiedRequest);
// Make a copy of the response to modify its headers
const modifiedResponse = new Response(response.body, response);
// Set CORS headers on the response
Object.keys(corsHeaders).forEach((header) => {
modifiedResponse.headers.set(header, corsHeaders[header]);
});
return modifiedResponse;
},
};Přepsání odkazů na stránkách HTML
Nahradí zastaralé odkazy, aniž byste museli cokoli měnit na origin serveru.
export default {
async fetch(request) {
// Define the old hostname here.
const OLD_URL = "oldsite.com";
// Then add your new hostname that should replace the old one.
const NEW_URL = "newsite.com";
class AttributeRewriter {
constructor(attributeName) {
this.attributeName = attributeName;
}
element(element) {
const attribute = element.getAttribute(this.attributeName);
if (attribute) {
element.setAttribute(
this.attributeName,
attribute.replace(OLD_URL, NEW_URL),
);
}
}
}
const rewriter = new HTMLRewriter()
.on("a", new AttributeRewriter("href"))
.on("img", new AttributeRewriter("src"));
const res = await fetch(request);
const contentType = res.headers.get("Content-Type");
// If the response is HTML, it can be transformed with
// HTMLRewriter -- otherwise, it should pass through
if (contentType.startsWith("text/html")) {
return rewriter.transform(res);
} else {
return res;
}
},
};Zpomalení požadavků
Definuje zpoždění, které se použije, pokud příchozí požadavky odpovídají vašemu pravidlu. Užitečné pro podezřelé požadavky.
export default {
async fetch(request) {
// Define delay
const delay_in_seconds = 5;
// Introduce a delay
await new Promise((resolve) =>
setTimeout(resolve, delay_in_seconds * 1000),
); // Set delay in milliseconds
// Pass the request to the origin
const response = await fetch(request);
return response;
},
};Společné používání Snippets a Workers
Snippets a Workers mají odlišné možnosti, ale dokážou spolupracovat při zpracování složitých pracovních postupů provozu.
Aby nedocházelo ke konfliktům, měly by Snippets a Workers pracovat na oddělených cestách požadavků, nikoli běžet na stejné URL adrese. Nechte je načítat příslušné URL adresy jako subrequest v rámci vlastní logiky, čímž zajistíte plynulé provádění a správné chování cache.
Příklad 1: Předávání dat mezi Snippets a Workers
Snippets mohou upravit příchozí požadavky ještě předtím, než dorazí k Workeru, a Workers pak mohou tyto úpravy přečíst, provést další transformace a předat požadavek dál.
Snippet: přidání vlastní hlavičky
export default {
async fetch(request) {
// Get the current timestamp
const timestamp = Date.now();
const hexTimestamp = timestamp.toString(16);
// Clone request and add a custom header
const modifiedRequest = new Request(request, {
headers: new Headers(request.headers),
});
modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);
console.log(`X-Hex-Timestamp: ${hexTimestamp}`);
// Pass modified request to origin
return fetch(modifiedRequest);
},
};Worker: Přečtení hlavičky a její přidání do odpovědi
export default {
async fetch(request) {
const response = await fetch("https://{snippets_url}", request); // Ensure {snippets_url} points to the endpoint modified by Snippets
const newResponse = new Response(response.body, response);
let hexTimestamp = request.headers.get("X-Hex-Timestamp") || "null";
console.log(hexTimestamp);
newResponse.headers.set("X-Hex-Timestamp", hexTimestamp);
return newResponse;
},
};Výsledek: Snippet nastavuje X-Hex-Timestamp, který Worker čte a předává origin serveru.
Příklad 2: Ukládání odpovědí Worker do mezipaměti pomocí Snippets
Worker provádí výpočetně náročné zpracování (například transformaci obrázků), zatímco Snippet obsluhuje výsledky z mezipaměti, aby se předešlo zbytečnému spouštění Workeru. To se hodí v situacích, kdy spouštění Workers před mezipamětí není žádoucí.
Worker: Transformace a ukládání odpovědí do mezipaměti
export default {
async fetch(request) {
const url = new URL(request.url);
url.hostname = "origin.example.com"; // Ensure this hostname points to the origin where the resource is hosted
const newRequest = new Request(url, request);
const customKey = `https://${url.hostname}${url.pathname}`; // This custom cache key should be the same in both Worker and Snippet configuration for cache to work
// Fetch and modify response
const response = await fetch(newRequest);
const newResponse = new Response(response.body, response);
// Cache the transformed response
const cache = caches.default;
const cachedResponse = newResponse.clone();
cachedResponse.headers.set("X-Cached-In-Workers", "true");
await cache.put(customKey, cachedResponse);
newResponse.headers.set("X-Retrieved-From-Workers", "true");
return newResponse;
},
};Snippet: doručení odpovědí z cache nebo předání Workeru
export default {
async fetch(request) {
const url = new URL(request.url);
url.hostname = "origin.example.com"; // Ensure this hostname points to the origin where the resource is hosted
const cacheKey = `https://${url.hostname}${url.pathname}`; // This custom cache key should be the same in both Worker and Snippet configuration for cache to work
// Access cache
const cache = caches.default;
let response = await cache.match(cacheKey);
if (!response) {
console.log(`Cache miss for: ${cacheKey}. Fetching from Worker...`);
url.hostname = "worker.example.com"; // Ensure this hostname points to the Workers route
response = await fetch(new Request(url, request));
// Cache the response for future use
response = new Response(response.body, response);
response.headers.set("Cache-Control", `s-maxage=3600`);
response.headers.set("x-snippets-cache", "stored");
} else {
console.log(`Cache hit for: ${cacheKey}`);
response = new Response(response.body, response);
response.headers.set("x-snippets-cache", "hit");
}
return response;
},
};Výsledek: Transformovaná odpověď (X-Cached-In-Workers: true) se obsluhuje z cache, čímž se předchází zbytečnému spouštění Workeru (X-Retrieved-From-Workers není přítomna). Po vypršení platnosti mezipaměti si Snippet vyžádá novou verzi.
Migrace mezi Snippets a Workers
Snippets a Workers sdílejí stejné Workers runtime, což znamená, že kód JavaScript, který nezávisí na bindings, trvalém úložišti ani pokročilých spouštěcích funkcích, lze mezi nimi bez problémů přenášet.
Kdy migrovat úlohy na Snippets
Migraci Worker na Snippets byste měli zvážit, pokud:
- Pouze upravuje hlavičky, přesměrování, pravidla cachování nebo směrování na origin.
- Nevyžaduje bindings, trvalé úložiště ani externí integrace.
- Je to odlehčená funkce v JavaScriptu s jednoduchou logikou.
- V plánu Pro, Business nebo Enterprise musí být možné jej spustit neomezeně mnohokrát zdarma.
Přechod na Snippets vám umožňuje:
- Využijte pokročilé porovnávání požadavků pomocí Ruleset Engine.
- Odstraňte účtování podle využití: Snippets jsou zahrnuto bez příplatku ve všech placených plánech.
- Správu si zjednodušíte tím, že úpravy provozu integrujete přímo do Cloudflare Rules.
Kdy migrovat úlohy na Workers
Ze Snippets na Workers byste měli přejít, pokud vaše logika:
- Překračuje dobu běhu, paměť nebo jiné limity.
- Vyžaduje správu trvalého stavu, například:
- Provádí výpočetně náročné operace, včetně:
- Spolupracuje s Cloudflare Developer Platform.
- Vyžaduje jednotkové testování.
- Vyžaduje automatizaci nasazení přes CLI (Wrangler).
Pokud váš Snippet narazí na limity doby běhu, paměti nebo funkčnosti, přechod na Workers zajistí, že se vaše logika bude moci škálovat bez omezení.
Závěr
Cloudflare Snippets nabízí produkčně připravené řešení pro rychlou deklarativní logiku provozu na edge a překlenují propast mezi Cloudflare Rules a Developer Platform.
Snippets a Workers řeší odlišné problémy:
- Snippets použijte pro rychlé, lehké úpravy provozu na edge, včetně přepisu hlaviček, cachování, přesměrování, směrování na origin, vlastních odpovědí, A/B testování a autentizace.
- Workers jsou určeny pro pokročilé výpočty, trvalý stav a fullstack aplikace.