← Cloudflare Turnstile / turnstile / get-started
Vložení widgetu
Jak přidat widget Turnstile na webovou stránku pomocí implicitního nebo explicitního vykreslení.
Turnstile nabízí dva způsoby, jak widget přidat na stránku. Implicitní vykreslování automaticky prohledá vaše HTML a najde kontejnery widgetů, jakmile se stránka načte. Explicitní vykreslování vám dává programovou kontrolu nad tím, kdy widget v JavaScriptu vytvoříte. Implicitní vykreslování použijte u statických stránek, kde formuláře existují už při načtení. Explicitní vykreslování použijte u dynamického obsahu a jednostránkových aplikací (SPA), kde formuláře vznikají až po prvotním načtení stránky.
| Funkce | Implicitní vykreslování | Explicitní vykreslování |
|---|---|---|
| Snadnost nastavení | Jednoduchý, minimální kód | Vyžaduje další JavaScript |
| Kontrola nad načasováním | Vykreslí se automaticky při načtení stránky | Plná kontrola nad načasováním vykreslení |
| Případy použití | Statický obsah | Dynamický nebo interaktivní obsah |
| Přizpůsobení | Omezeno na atributy HTML | Rozsáhlé možnosti přes JavaScript API |
Předpoklady
Než začnete, budete potřebovat:
- Účet Cloudflare
- Widget Turnstile se sitekey
- Možnost upravovat HTML svého webu
- Základní znalost HTML a JavaScriptu
Postup
- Načtení stránky: skript Turnstile se načte a vyhledá příslušné prvky, případně čeká na programové volání.
- Vykreslení widgetu: widgety se vytvoří a začnou spouštět výzvy.
- Generování tokenu: po dokončení výzvy se vygeneruje token.
- Integrace do formuláře: token se předává přes callbacky nebo skrytá pole formuláře.
- Ověření na serveru: váš server token převezme a ověří jej přes Siteverify API.
Implicitní vykreslování
Implicitní vykreslování automaticky prohledá vaše HTML a najde prvky s cf-turnstile a vykreslí widgety bez dalšího JavaScriptového kódu. Toto nastavení je ideální pro statické stránky, kde má být widget načtený hned se stránkou.
Případy použití
Cloudflare doporučuje použít implicitní vykreslování v těchto případech:
- Máte jednoduchou implementaci a chcete rychlou integraci.
- Máte statické weby s jednoduchými formuláři.
- Chcete, aby se widgety zobrazily hned při načtení stránky.
- Nepotřebujete widget ovládat programově.
Implementace
1. Přidejte skript Turnstile
Vložení skriptu Turnstile: Přidejte JavaScriptové API Turnstile do souboru HTML uvnitř prvku <head> nebo těsně před uzavírací </body> .
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async
defer
></script>2. (Volitelné) Optimalizujte výkon pomocí resource hints
Přidejte resource hints, které naváží spojení se servery Cloudflare s předstihem a zrychlí načítání. Umístěte tento <link> ve svém HTML <head> před skript Turnstile.
<link rel="preconnect" href="https://challenges.cloudflare.com" />3. Přidejte prvky widgetu
Na místa, kde se mají výzvy na webu zobrazit, vložte kontejnery widgetu.
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>4. Nastavte pomocí datových atributů
Přizpůsobení widgetů pomocí datových atributů. Vložte div element tam, kam chcete widget umístit.
<div
class="cf-turnstile"
data-sitekey="<YOUR-SITE-KEY>"
data-theme="light"
data-size="normal"
data-callback="onSuccess"
></div>Po vyřešení výzvy se do success callbacku předá token. Ten je nutné ověřit proti našemu Endpoint Siteverify.
Kompletní příklady implicitního vykreslování podle scénářů
Základní přihlašovací formulář
Turnstile se často používá k ochraně formulářů na webech, například přihlašovacích nebo kontaktních. Widget vložíte přímo do svého <form> .
<!DOCTYPE html>
<html>
<head>
<title>Login Form</title>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>
<form action="/login" method="POST">
<input type="text" name="username" placeholder="Username" autocomplete="username" required />
<input type="password" name="password" placeholder="Password" autocomplete="current-password" required />
<!-- Turnstile widget with basic configuration -->
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
<button type="submit">Log in</button>
</form>
</body>
</html>Neviditelný input s názvem cf-turnstile-response se přidá a odešle se na server spolu s ostatními poli.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Implicit Rendering with Cloudflare Turnstile</title>
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async
defer
></script>
</head>
<body>
<h1>Contact Us</h1>
<form action="/submit" method="POST">
<label for="name">Name:</label><br />
<input type="text" id="name" name="name" required /><br />
<label for="email">Email:</label><br />
<input type="email" id="email" name="email" required /><br />
<!-- Turnstile Widget -->
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
<br />
<button type="submit">Submit</button>
</form>
</body>
</html>Pokročilý formulář s callbacky
<form action="/contact" method="POST" id="contact-form">
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required></textarea>
<!-- Widget with callbacks and custom configuration -->
<div
class="cf-turnstile"
data-sitekey="<YOUR-SITE-KEY>"
data-theme="auto"
data-size="flexible"
data-callback="onTurnstileSuccess"
data-error-callback="onTurnstileError"
data-expired-callback="onTurnstileExpired"
></div>
<button type="submit" id="submit-btn" disabled>Send Message</button>
</form>
<script>
function onTurnstileSuccess(token) {
console.log("Turnstile success:", token);
document.getElementById("submit-btn").disabled = false;
}
function onTurnstileError(errorCode) {
console.error("Turnstile error:", errorCode);
document.getElementById("submit-btn").disabled = true;
}
function onTurnstileExpired() {
console.warn("Turnstile token expired");
document.getElementById("submit-btn").disabled = true;
}
</script>Více widgetů s odlišnou konfigurací
<!-- Compact widget for newsletter signup -->
<form action="/newsletter" method="POST">
<input type="email" name="email" placeholder="Email" />
<div
class="cf-turnstile"
data-sitekey="<YOUR-SITE-KEY>"
data-size="compact"
data-action="newsletter"
></div>
<button type="submit">Subscribe</button>
</form>
<!-- Normal widget for contact form -->
<form action="/contact" method="POST">
<input type="text" name="name" placeholder="Name" />
<input type="email" name="email" placeholder="Email" />
<textarea name="message" placeholder="Message"></textarea>
<div
class="cf-turnstile"
data-sitekey="<YOUR-SITE-KEY>"
data-action="contact"
data-theme="dark"
></div>
<button type="submit">Send</button>
</form>Automatická integrace s formulářem
Když widget Turnstile vložíte do <form> elementu neviditelné vstupní pole s názvem cf-turnstile-response se vytvoří automaticky. Obsahuje ověřovací token a odesílá se společně s ostatními daty formuláře.
<form action="/submit" method="POST">
<input type="text" name="data" />
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
<!-- Hidden field automatically added: -->
<!-- <input type="hidden" name="cf-turnstile-response" value="TOKEN_VALUE" /> -->
<button type="submit">Submit</button>
</form>Explicitní vykreslování
Explicitní vykreslování vám dává programovou kontrolu nad tím, kdy a kde se widget zobrazí a jak se widgety vytvářejí pomocí funkcí JavaScriptu. Tento postup se hodí pro dynamický obsah, jednostránkové aplikace (SPA) nebo podmíněné vykreslování podle akcí uživatele.
Případy použití
Cloudflare doporučuje použít explicitní vykreslování v těchto případech:
- Máte dynamické weby a jednostránkové aplikace (SPA).
- Potřebujete řídit, kdy se widget vytvoří.
- Chcete widget vykreslovat podmíněně podle interakcí návštěvníka.
- Chcete více widgetů s různým nastavením.
- Máte složité aplikace, které vyžadují správu životního cyklu widgetu.
Implementace
1. Přidejte skript na web s explicitním vykreslováním
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"
defer
></script>2. Vytvořte kontejnerové prvky
Vytvořte kontejnery bez cf-turnstile třídu.
<div id="turnstile-container"></div>3. Vykreslete widgety programově
Zavolejte turnstile.render() až budete připraveni widget vytvořit.
const widgetId = turnstile.render("#turnstile-container", {
sitekey: "<YOUR-SITE-KEY>",
callback: function (token) {
console.log("Success:", token);
},
});Volitelná volání
Po explicitním vykreslení widgetu Turnstile s ním podle potřeb vaší aplikace obvykle dále pracujete. Jak spravovat stav widgetu, popisují následující části.
Resetování widgetu
Pokud danému widgetu vypršel časový limit nebo platnost, resetujete ho touto funkcí:
turnstile.reset(widgetId);Získání response tokenu
Aktuální token odpovědi můžete kdykoli získat:
const responseToken = turnstile.getResponse(widgetId);Odstranění widgetu
Jakmile už widget není potřeba, můžete ho ze stránky odstranit pomocí:
turnstile.remove(widgetId);Nezavolá se žádný callback a odstraní se všechny související prvky DOM.
Kompletní příklady explicitního vykreslování podle scénářů
Základní explicitní implementace
<!DOCTYPE html>
<html>
<head>
<title>Explicit Rendering</title>
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"
defer
></script>
</head>
<body>
<form id="login-form">
<input
type="text"
name="username"
placeholder="Username"
autocomplete="username"
/>
<input
type="password"
name="password"
placeholder="Password"
autocomplete="current-password"
/>
<div id="turnstile-widget"></div>
<button type="submit">Login</button>
</form>
<script>
window.onload = function () {
turnstile.render("#turnstile-widget", {
sitekey: "<YOUR-SITE-KEY>",
callback: function (token) {
console.log("Turnstile token:", token);
// Handle successful verification
},
"error-callback": function (errorCode) {
console.error("Turnstile error:", errorCode);
},
});
};
</script>
</body>
</html>Použití callbacku onload
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=onTurnstileLoad"
defer
></script>
<div id="widget-container"></div>
<script>
function onTurnstileLoad() {
turnstile.render("#widget-container", {
sitekey: "<YOUR-SITE-KEY>",
theme: "light",
callback: function (token) {
console.log("Challenge completed:", token);
},
});
}
</script>Pokročilá implementace v SPA
<div id="dynamic-form-container"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"></script>
<script>
class TurnstileManager {
constructor() {
this.widgets = new Map();
}
createWidget(containerId, config) {
// Wait for Turnstile to be ready
turnstile.ready(() => {
const widgetId = turnstile.render(containerId, {
sitekey: config.sitekey,
theme: config.theme || "auto",
size: config.size || "normal",
callback: (token) => {
console.log(`Widget ${widgetId} completed:`, token);
if (config.onSuccess) config.onSuccess(token, widgetId);
},
"error-callback": (error) => {
console.error(`Widget ${widgetId} error:`, error);
if (config.onError) config.onError(error, widgetId);
},
});
this.widgets.set(containerId, widgetId);
return widgetId;
});
}
removeWidget(containerId) {
const widgetId = this.widgets.get(containerId);
if (widgetId) {
turnstile.remove(widgetId);
this.widgets.delete(containerId);
}
}
resetWidget(containerId) {
const widgetId = this.widgets.get(containerId);
if (widgetId) {
turnstile.reset(widgetId);
}
}
}
// Usage
const manager = new TurnstileManager();
// Create a widget when user clicks a button
document.getElementById("show-form-btn").addEventListener("click", () => {
document.getElementById("dynamic-form-container").innerHTML = `
<form>
<input type="email" placeholder="Email" />
<div id="turnstile-widget"></div>
<button type="submit">Submit</button>
</form>
`;
manager.createWidget("#turnstile-widget", {
sitekey: "<YOUR-SITE-KEY>",
theme: "dark",
onSuccess: (token) => {
// Handle successful verification
console.log("Form ready for submission");
},
});
});
</script>Správa životního cyklu widgetu
Explicitní vykreslování dává plnou kontrolu nad životním cyklem widgetu.
// Render a widget
const widgetId = turnstile.render("#container", {
sitekey: "<YOUR-SITE-KEY>",
callback: handleSuccess,
});
// Get the current token
const token = turnstile.getResponse(widgetId);
// Check if widget is expired
const isExpired = turnstile.isExpired(widgetId);
// Reset the widget (clears current state)
turnstile.reset(widgetId);
// Remove the widget completely
turnstile.remove(widgetId);Režim spouštění
Pomocí režimů spuštění určete, kdy se výzvy spouštějí.
// Render widget but don't run challenge yet
const widgetId = turnstile.render("#container", {
sitekey: "<YOUR-SITE-KEY>",
execution: "execute", // Don't auto-execute
});
// Later, run the challenge when needed
turnstile.execute("#container");Optimalizace výkonu a uživatelského prožitku
Cloudflare doporučuje spustit skript Turnstile co nejdříve po vstupu návštěvníka na stránku, aby ověření stihlo doběhnout a interakce byla připravená ve chvíli, kdy návštěvník na stránce něco udělá.
Možnosti konfigurace
Implicitní i explicitní způsob vykreslení podporuje stejné možnosti konfigurace. Nejčastěji používané najdete v tabulce níže.
| Možnost | Popis | Hodnoty |
|---|---|---|
sitekey |
Sitekey vašeho widgetu | Povinný řetězec |
theme |
Vizuální motiv | auto, light, dark |
size |
Velikost widgetu | normal, flexible, compact |
callback |
Callback při úspěchu | Funkce |
error-callback |
Callback při chybě | Funkce |
execution |
Kdy spustit výzvu | render, execute |
appearance |
Kdy je widget viditelný | always, execute, interaction-only |
Úplný seznam možností konfigurace najdete v Konfigurace widgetů.
Testování
Pomocí testovacího sitekey si widget Turnstile na své stránce vyzkoušíte, aniž by se spustil skutečný Cloudflare Challenge.
Viz Testování s dalšími informacemi.
Omezení
Turnstile funguje pouze na stránkách, které používají http:// nebo https:// schémata URI. Ostatní protokoly, například file://, nejsou pro vložení widgetu podporovány.
Bezpečnostní požadavky
-
Ověřování na straně serveru je povinné. Tokeny Turnstile je nutné vynutit přes Siteverify API. Token Turnstile může být neplatný, prošlý nebo už uplatněný. Pokud jej neověříte, zůstanou ve vaší implementaci zásadní zranitelnosti. Volání Siteverify patří k dokončené konfiguraci Turnstile. Bez něj je konfigurace neúplná a ověření tokenů bude vykazovat nuly v metrikách v Turnstile Analytics.
-
Tokeny vyprší po 300 sekundách (5 minutách). Každý token lze ověřit jen jednou. Vypršené nebo použité tokeny je nutné nahradit novou výzvou.