WordPress·3 min lezen

Gravity Forms-inzending komt niet aan: verlopen nonces in LiteSpeed Cache

Formulier ingevuld, maar geen inzending, geen spam en geen mail? Bij LiteSpeed Cache zijn de nonces in de gecachete pagina vaak verlopen. Zo vind je het.

Klanten zeggen dat ze het contactformulier hebben ingevuld, maar er komt niets binnen en er staat niets bij de inzendingen. Zoek in de access-log van vandaag uit wat er met de formulier-POSTs gebeurt.

"Ik heb het formulier toch ingevuld?" Die vraag kwam binnen bij een site met Gravity Forms en LiteSpeed Cache. Er stond geen inzending in WordPress, niets in de spammap en er was geen mail verstuurd. De bezoeker had niets verkeerd gedaan. De oorzaak zat in de cache.

Waarom is er nergens een spoor?

Gravity Forms bewaart een inzending die op de controle afketst nergens. Geen entry, geen spam, geen mail. De bezoeker ziet het formulier opnieuw, denkt dat het gelukt is of geeft het op. De inhoud van een POST staat niet in de access-log, en de logging van Gravity Forms staat meestal uit. Wie dan in de mailserver of de spamfilter zoekt, zoekt op de verkeerde plek.

Wat is de oorzaak?

WordPress zet in formulieren een nonce: een code die bewijst dat het formulier echt van jouw site komt. Zo'n nonce is 12 tot 24 uur geldig. LiteSpeed Cache bewaarde de pagina met het formulier in dit geval 7 dagen (cache-ttl_pub op 604800 seconden). Een bezoeker kreeg dus een pagina met nonces die al dagen verlopen waren.

Twee onderdelen struikelden daarover:

  • Bestanden uploaden. De upload gaat met een POST naar /?gf_page=<code>. Die gaf een 403 met een antwoord van 93 bytes: Gravity Forms meldt dat de sessie verlopen is.
  • reCAPTCHA v3. De reCAPTCHA-uitbreiding van Gravity Forms heeft ook een nonce in de pagina. Is die verlopen, dan is het token leeg of ongeldig en keurt de controle de hele inzending af.

Hoe herken je het in de access-log?

Filter de access-log van de dag op POSTs naar de formulierpagina en op gf_page:

grep 'POST' access.log | grep -E 'gf_page|/contact'
grep 'gf_page=' access.log | awk '$9 == 403'

Het patroon dat wij zagen:

  1. Eerste POST vanaf de gecachete pagina: 200, met een antwoord dat groter is dan de gewone pagina. Dat is het formulier opnieuw, met een foutmelding. De inzending is afgewezen.
  2. Tweede POST, nu vanaf de verse pagina die net terugkwam: die lukt wel.
  3. Een geslaagde inzending met een doorverwijzing naar een bedankpagina is een POST met 302 naar die pagina.

Let op de tijden. De access-log staat in lokale tijd, de inzendingen in de database (wp_gf_entry.date_created) in UTC. In de zomer scheelt dat twee uur.

Hoe controleer je de cache?

Kijk of de formulierpagina uit de cache komt, en hoe lang die cache duurt:

curl -sI https://www.jouwdomein.nl/contact/ | grep -i x-litespeed-cache
wp litespeed-option get cache-ttl_pub

x-litespeed-cache: hit betekent dat de pagina uit de cache komt. Staat de TTL boven de 43200 seconden (12 uur), dan kan een bezoeker een pagina krijgen met een nonce die niet meer geldig is.

Hoe los je het op?

Zet de publieke cache korter dan 12 uur en leeg de cache, zodat er geen oude pagina's meer rondgaan:

wp litespeed-option set cache-ttl_pub 36000
wp litespeed-purge all

36000 seconden is 10 uur. Elke gecachete pagina is dan jonger dan de kortste geldigheid van een nonce.

Wil je de lange cache houden, dan zijn er twee andere wegen. LiteSpeed Cache kan nonces met ESI los van de pagina vullen; dan moeten de nonces van Gravity Forms en reCAPTCHA in de nonce-lijst van de plugin staan. Of je sluit alleen de pagina's met een formulier uit van de cache.

Veelgemaakte fouten

Zoeken in de mail. Er is nooit een mail verstuurd. De inzending is al bij de controle afgewezen.

Denken dat de bezoeker iets fout deed. De tweede poging lukt vaak wel, omdat de pagina dan vers is. Dat lijkt op gebruikersfout, maar het is de cache.

De cache helemaal uitzetten. Dat maakt je site trager voor iedereen. Een TTL onder de 12 uur lost het ook op.

Vergeten te legen. Na het aanpassen van de TTL blijven oude pagina's in de cache staan tot ze verlopen. Leeg de cache meteen.

Tijden één op één vergelijken. Access-log in lokale tijd, database in UTC.

Verder lezen

MK
Maarten Keizer

Oprichter van Invoker. Ruim twintig jaar hosting, systeembeheer en webdevelopment; bouwt de Claude-hosting zelf en test alles eerst op de eigen servers.

over maarten