# Simple 'Donut Hole' Caching con HTMX

# El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

El caché de donut hole puede ser una técnica útil en la que se quiere cachar determinados elementos de una página pero no todos. Sin embargo, puede ser difícil de aplicar. En este post voy a mostrarle cómo implementar una simple técnica de caché del donuthole utilizando HTMXM SK2

<!--category-- HTMX, Razor, ASP.NET -->
<datetime class="hidden">2024-09-12T16:00</datetime>
[TOC]

# El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

Un problema que estaba teniendo con este sitio es que quería usar Anti-toques de falsificación con mis formularios . Esta es una buena práctica de seguridad para evitar ataques Cross-Forgeración de Referencias de Sitio MSC3CSRFM SK4 Sin embargoMST6 esto causó un problema con el cacheo de las páginasMst7 El Toqueo Anti\MST8\forgery es único a cada petición de páginaM st9 por lo tanto, si caches la página M st10 el toqueo será el mismo para todos los usuariosMstr11 Esto significa que si un usuario envía un formularioM str12 el símbolo será inválido y la presentación del formulario fracasaráM t13 ASP\M st14NET Core impide esto desactivando todo el cacho en petición donde se usa el Toco Anti\mst15\forgerieM sct16 Esta é una buena prácticas de seguridadMt17 pero esto significa que la página no será cachéa en absolutoM d18 Esto no es ideal para un sitio como este, donde el contenido es principalmente staticM m st19

# El Presidente (habla en inglés): De conformidad con el entendimiento alcanzado en las consultas previas del Consejo, consideraré que la Asamblea General desea concluir su examen de este tema del programa.

Una manera común de hacer esto es 'donut hole' caching donde caches la mayoría de la página pero determinados elementos.

Como ya uso el excelente [El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.](https://htmx.org/examples/lazy-load/) en este proyecto hay' una manera super sencilla de obtener la funcionalidad dinámica M SK1donut hole' mediante cargación dinámica de partes con HTMXMSC3
Ya he escrito un blog sobre [utilizando Toques AntiForgeryRequest con Javascript](/blog/addingxsrfforjavascript) Sin embargo, de nuevo la cuestión era que esto efectivamente desactivaba el caching para la página.

Ahora puedo reinstaurar esta funcionalidad cuando utilizo HTMX para cargar de manera dinámica partiales.

```razor
  <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>
```

Simples muertos, derechoM SK1 Todo esto hace es llamar a la línea de código en el controlador que devolve la vista parcial . Esto significa que el token Anti-forgery se genera en el servidor y la página puede almacenarse en caché como normalMSC4 La vista parcial está cargada de forma dinámica, por lo cual el toco sigue siendo único para cada peticiónMNK5

NOTA: Usted si utiliza un enfoque 'SPAM SK2 como yo lo uso con HTMX necesita asegurarse de que el `load` event doesn't fire again on the back button. Yo lo haga haciendo mediante la configuración de typeahead para superescribir el objetivo en la primera carga.

Esto significa que la primera vez que se ejecuta elimina el div originario y lo sustituye por el nuevo contenido de la parte devolvida por el controlador de abajo. Puesto que el token de falsificación Anto-se genera en el servidor y se almacena en un cookie de sesión, debería seguir funcionando con este enfoque M SK2hasta que replante la aplicación ).

Por consiguiente, el Comité recomienda al Estado Parte que adopte todas las medidas necesarias para: `hx-target` a el elemento externo principalmente para evitar un error JS; ya que HTMX necesita un objetivo válido al completar la solicitudM SK1 Así que usted puede' no eliminar el elemento que desencadenó la petición de HT MX .

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

Dentro del partial todavía tenemos la forma simple con el símbolo Anti-forgery.

```razor
<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>
```

Esto then encapsulates all the code for the typeahead search and when it's submitted it pulls the token and adds it to the request (exactly as beforeM SK2

```javascript
        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
                }
            })
```

# El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

Esta es una manera super sencilla de obtener 'donut hole' caching con HTMXMSC2 EsM SK3una gran forma de obtener los beneficios del caching sin la complejidad de un paquete extraMST4 Espero que encuentres esto útilMst5 Permítanme saber si tiene alguna pregunta en los comentarios de abajoM st6