Eenvoudig 'Donut Hole' Caching met HTMX (Nederlands (Dutch))

Eenvoudig 'Donut Hole' Caching met HTMX

Thursday, 12 September 2024

//

4 minute read

Inleiding

Donut hole caching kan een nuttige techniek zijn waarbij je bepaalde elementen van een pagina, maar niet alle, cachet.. Het is echter moeilijk om te implementeren.

Het probleem

Eén probleem dat ik met deze site had, is dat ik Anti-false tokens wilde gebruiken met mijn formulieren. Dit is een goede veiligheidspraktijk om Cross-of-Site-Bezoeken-falseting te voorkomen M SK3CSRF)aanvallen . Maar, het veroorzaakte een probleem met de caching van de pagina'sMSC7 Het Anti-falsentoken is uniek voor elke pagina-requestMska9 dus als je de pagina in cachetMsek10 zal het token hetzelfde zijn voor alle gebruikersMske11 Dat betekent dat als een gebruiker een vorm instuurt, de token ongeldig zal zijn en de vormsubmissie zal mislukken.

De oplossing

Een gemeenschappelijke manier om hierom heen is 'donut hole' caching waar je de meeste pagina's, maar bepaalde elementen, cachet.

Omdat ik al gebruik van de excellente HTMX In dit project is ' een super eenvoudige manier om dynamische functionaliteit te krijgen met HTMX-deeltjes te laden. Ik heb er al over geblogd. Met AntiForgeryRequest Tokens met Javascript Maar nogmaals, het probleem was dat dit het caching van de pagina effectief afbracht.

Nu kan ik deze functionaliteit herstellen bij het gebruik van HTMX om deeltjes dynamisch te laden.

  <li class="group relative mb-1 hidden lg:block ml-2" id="typeaheadelement">
    <div  hx-trigger="load" hx-get="/typeahead" hx-target="#typeaheadelement" hx-swap="innerHTML"></div>
</li>

Dood eenvoudig, rechts? Alles wat dit doet, is roepen in de ene regel van de code in de controller die het gedeeltelijke beeld teruggeeft.

NOTA: Als je een 'SPA'-achtige aanpak gebruikt zoals ik het doe met HTMX, moet je ervoor zorgen dat de load event doesn't fire again on the back button. Ik laat dit gebeuren door het instellen van de typehead om het doel op de eerste lading te overschrijven.

Dit betekent dat het de eerste keer dat het draait, het de oorspronkelijke div cleart en het vervangt met de nieuwe inhoud van het gedeelte dat door de controller teruggestuurd wordt.

We stelden de hx-target naar het externe element, vooral om een JS fout te voorkomen; omdat HTMX een geldige doelwit nodig heeft bij het voltooien van de versoek. Je kunt het element dat de HT MX- versoek uitbracht niet verwijderen.

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    [HttpGet("typeahead")]
    public IActionResult TypeAhead()
    {
        return PartialView("_TypeAhead");
    }

Binnen het gedeeltelijk hebben we nog steeds de eenvoudige vorm met de Anti-gefälseerd token.

<div x-data="window.mostlylucid.typeahead()" class="relative" id="searchelement"  x-on:click.outside="results = []">
    @Html.AntiForgeryToken()
    <label class="input input-sm dark:bg-custom-dark-bg bg-white input-bordered flex items-center gap-2">
        <input
            type="text"
            x-model="query"
            x-on:input.debounce.300ms="search"
            x-on:keydown.down.prevent="moveDown"
            x-on:keydown.up.prevent="moveUp"
            x-on:keydown.enter.prevent="selectHighlighted"
            placeholder="Search..."
            class="border-0 grow  input-sm text-black dark:text-white bg-transparent w-full"/>
        <i class="bx bx-search"></i>
    </label>
    <!-- Dropdown -->
    <ul x-show="results.length > 0"
        class="absolute z-10 my-2 w-full bg-white dark:bg-custom-dark-bg border border-1 text-black dark:text-white border-b-neutral-600 dark:border-gray-300   rounded-lg shadow-lg">
        <template x-for="(result, index) in results" :key="result.slug">
            <li
                x-on:click="selectResult(result)"
                :class="{
                    'dark:bg-blue-dark bg-blue-light': index === highlightedIndex,
                    'dark:hover:bg-blue-dark hover:bg-blue-light': true
                }"
                class="cursor-pointer text-sm p-2 m-2"
                x-text="result.title"
            ></li>
        </template>
    </ul>
</div>

Dit omvat dan alle code voor de typahead- zoekopdracht en als het 's ingestuurd is, trekt het token en voegt het toe aan de verzoek.

        let token = document.querySelector('#searchelement input[name="__RequestVerificationToken"]').value;
            console.log(token);
            fetch(`/api/search/${encodeURIComponent(this.query)}`, { // Fixed the backtick and closing bracket
                method: 'GET', // or 'POST' depending on your needs
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': token // Attach the AntiForgery token in the headers
                }
            })

In slotting:

Dit is een super eenvoudige manier om te krijgen 'donut hole' caching met HTMX. Het is een geweldige manier om de voordelen van caching te krijgen zonder de complexiteit van een extra pakket.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.