Este es un paquete diseñado para agregar métodos auxiliares del lado del servidor para HttpRequest
y HttpResponse
. Esto simplifica el trabajo con conceptos del lado del servidor htmx. También deberías considerar leer sobre Hyperscript, un proyecto complementario opcional para HTMX.
Si es nuevo en HTMX, consulte esta serie sobre cómo comenzar con HTMX para desarrolladores de ASP.NET Core, que también incluye un proyecto de muestra y patrones que pueden resultarle útiles.
Instale el paquete Htmx
NuGet en su proyecto ASP.NET Core.
dotnet add package Htmx
Usando HttpRequest
, podemos determinar si la solicitud fue iniciada por Htmx en el cliente.
httpContext . Request . IsHtmx ( )
Esto se puede utilizar para devolver una respuesta de página completa o una representación de página parcial.
// in a Razor Page
return Request . IsHtmx ( )
? Partial ( " _Form " , this )
: Page ( ) ;
También podemos recuperar los otros valores de encabezado que htmx pueda establecer.
Request . IsHtmx ( out var values ) ;
Lea más sobre los otros valores de encabezado en la página de documentación oficial.
Como nota especial, tenga en cuenta que si su servidor puede representar contenido diferente para la misma URL dependiendo de otros encabezados, deberá utilizar el encabezado HTTP de respuesta Variar. Por ejemplo, si su servidor muestra el HTML completo cuando Request.IsHtmx() es falso y muestra un fragmento de ese HTML cuando Request.IsHtmx() es verdadero, debe agregar Vary: HX-Request. Esto hace que la clave del caché se base en una combinación de la URL de respuesta y el encabezado de solicitud HX-Request, en lugar de basarse solo en la URL de respuesta.
// in a Razor Page
if ( Request . IsHtmx ( ) )
{
Response . Headers . Add ( " Vary " , " HX-Request " ) ;
return Partial ( " _Form " , this )
}
return Page ( ) ;
Podemos configurar encabezados de respuesta Http utilizando el método de extensión Htmx
, que pasa una acción y un objeto HtmxResponseHeaders
.
Response . Htmx ( h => {
h . PushUrl ( " /new-url " )
. WithTrigger ( " cool " )
} ) ;
Lea más sobre los encabezados de respuesta HTTP en el sitio de documentación oficial.
Puede activar eventos del lado del cliente con HTMX utilizando el encabezado HX-Trigger
. Htmx.Net proporciona un método auxiliar WithTrigger
para configurar uno o más eventos que desea activar.
Response . Htmx ( h => {
h . WithTrigger ( " yes " )
. WithTrigger ( " cool " , timing : HtmxTriggerTiming . AfterSettle )
. WithTrigger ( " neat " , new { valueForFrontEnd = 42 , status = " Done! " } , timing : HtmxTriggerTiming . AfterSwap ) ;
} ) ;
De forma predeterminada, todas las solicitudes y respuestas Htmx se bloquearán en un contexto de origen cruzado.
Si configura su aplicación en un contexto de origen cruzado, establecer una política CORS en ASP.NET Core también le permite definir restricciones específicas en los encabezados de solicitud y respuesta, lo que permite un control detallado sobre los datos que se pueden intercambiar entre su sitio web. aplicación y diferentes orígenes.
Esta biblioteca proporciona un enfoque simple para exponer encabezados Htmx a su política CORS:
var MyAllowSpecificOrigins = " _myAllowSpecificOrigins " ;
var builder = WebApplication . CreateBuilder ( args ) ;
builder . Services . AddCors ( options =>
{
options . AddPolicy ( name : MyAllowSpecificOrigins ,
policy =>
{
policy . WithOrigins ( " http://example.com " , " http://www.contoso.com " )
. WithHeaders ( HtmxRequestHeaders . Keys . All ) // Add htmx request headers
. WithExposedHeaders ( HtmxResponseHeaders . Keys . All ) // Add htmx response headers
} ) ;
} ) ;
Instale el paquete Htmx.TagHelpers
NuGet en su proyecto ASP.NET Core. Está dirigido a proyectos .NET Core 3.1+.
dotnet add package Htmx.TagHelpers
Haga que los asistentes de etiquetas estén disponibles en su proyecto agregando la siguiente línea a su _ViewImports.cshtml
:
@addTagHelper *, Htmx.TagHelpers
Por lo general, necesitará rutas URL que apunten a su backend de ASP.NET Core. Afortunadamente, Htmx.TagHelpers
imita la generación de URL incluida en ASP.NET Core. Esto hace que vincular HTMX con su aplicación ASP.NET Core sea una experiencia perfecta.
< div hx-target =" this " >
< button hx-get
hx-page =" Index "
hx-page-handler =" Snippet "
hx-swap =" outerHtml " >
Click Me (Razor Page w/ Handler)
</ button >
</ div >
< div hx-target =" this " >
< button hx-get
hx-controller =" Home "
hx-action =" Index "
hx-route-id =" 1 " >
Click Me (Controller)
</ button >
</ div >
< div hx-target =" this " >
< button hx-post
hx-route =" named " >
Click Me (Named)
</ button >
</ div >
Se incluye un asistente de etiqueta htmx-config
adicional que se puede aplicar a un meta
en head
de su página para simplificar la creación de la configuración HTMX. Por ejemplo, a continuación podemos configurar el historyCacheSize
, indicatorClass
predeterminadoClass y si incluir los tokens antifalsificación de ASP.NET Core como un elemento adicional en la configuración HTMX.
<!DOCTYPE html >
< html lang =" en " >
< head >
< meta name =" htmx-config "
historyCacheSize =" 20 "
indicatorClass =" htmx-indicator "
includeAspNetAntiforgeryToken =" true "
/>
<!-- additional elements... -->
</ head >
El HTML resultante será.
<!DOCTYPE html >
< html lang =" en " >
< head >
< meta name =" htmx-config " content =' {"indicatorClass":"htmx-indicator","historyCacheSize":20,"antiForgery":{"formFieldName":"__RequestVerificationToken","headerName":"RequestVerificationToken","requestToken":"<token>"}} ' />
<!-- additional elements... -->
</ head >
Puede configurar el atributo includeAspNetAntiforgerToken
en el elemento htmx-config
. Luego deberá incluir este JavaScript adicional en su aplicación web. Incluimos el atributo __htmx_antiforgery
para rastrear el detector de eventos que ya se agregó. Esto evita que volvamos a registrar accidentalmente el detector de eventos.
if ( ! document . body . attributes . __htmx_antiforgery ) {
document . addEventListener ( "htmx:configRequest" , evt => {
let httpVerb = evt . detail . verb . toUpperCase ( ) ;
if ( httpVerb === 'GET' ) return ;
let antiForgery = htmx . config . antiForgery ;
if ( antiForgery ) {
// already specified on form, short circuit
if ( evt . detail . parameters [ antiForgery . formFieldName ] )
return ;
if ( antiForgery . headerName ) {
evt . detail . headers [ antiForgery . headerName ]
= antiForgery . requestToken ;
} else {
evt . detail . parameters [ antiForgery . formFieldName ]
= antiForgery . requestToken ;
}
}
} ) ;
document . addEventListener ( "htmx:afterOnLoad" , evt => {
if ( evt . detail . boosted ) {
const parser = new DOMParser ( ) ;
const html = parser . parseFromString ( evt . detail . xhr . responseText , 'text/html' ) ;
const selector = 'meta[name=htmx-config]' ;
const config = html . querySelector ( selector ) ;
if ( config ) {
const current = document . querySelector ( selector ) ;
// only change the anti-forgery token
const key = 'antiForgery' ;
htmx . config [ key ] = JSON . parse ( config . attributes [ 'content' ] . value ) [ key ] ;
// update DOM, probably not necessary, but for sanity's sake
current . replaceWith ( config ) ;
}
}
} ) ;
document . body . attributes . __htmx_antiforgery = true ;
}
Puede acceder al fragmento de dos maneras. La primera es utilizar la clase estática HtmxSnippet
en sus vistas.
<script>
@Html.Raw(HtmxSnippets.AntiforgeryJavaScript)
</script>
Una forma más sencilla es utilizar la clase HtmlExtensions
que extiende IHtmlHelper
.
@Html.HtmxAntiforgeryScript()
Este asistente HTML dará como resultado una etiqueta <script>
junto con el JavaScript mencionado anteriormente. Nota: Aún puedes registrar varios controladores de eventos para htmx:configRequest
, por lo que está bien tener más de uno.
Tenga en cuenta que si el atributo hx-[get|post|put]
está en una etiqueta <form ..>
y el elemento <form>
tiene un atributo method="post"
(y también un atributo action=""
vacío o faltante), Los asistentes de etiquetas de ASP.NET agregarán el token antifalsificación como elemento input
y no necesitará configurar más sus solicitudes como se indicó anteriormente. También puedes usar hx-include
para apuntar a un formulario, pero todo esto se reduce a una cuestión de preferencia.
Además, el enfoque recomendado es utilizar HtmxAntiforgeryScriptEndpoint
, que le permitirá asignar el archivo JavaScript a un punto final específico y, de forma predeterminada, será _htmx/antiforgery.js
.
app . UseAuthorization ( ) ;
// registered here
app . MapHtmxAntiforgeryScript ( ) ;
app . MapRazorPages ( ) ;
app . MapControllers ( ) ;
Ahora puede configurar este punto final con almacenamiento en caché, autenticación, etc. Más importante aún, ahora puede usar el script en su etiqueta head
aplicando la etiqueta defer
, que es preferible a tener JavaScript al final de un elemento body
.
< head >
< meta charset =" utf-8 "/>
< meta name =" viewport " content =" width=device-width, initial-scale=1.0 "/>
< meta
name =" htmx-config "
historyCacheSize =" 20 "
indicatorClass =" htmx-indicator "
includeAspNetAntiforgeryToken =" true "/>
< title > @ViewData["Title"] - Htmx.Sample </ title >
< link rel =" stylesheet " href =" ~/lib/bootstrap/dist/css/bootstrap.min.css "/>
< link rel =" stylesheet " href =" ~/css/site.css " asp-append-version =" true "/>
< script src =" ~/lib/jquery/dist/jquery.min.js " defer > </ script >
< script src =" ~/lib/bootstrap/dist/js/bootstrap.bundle.min.js " defer > </ script >
< script src =" https://unpkg.com/htmx.org@@1.9.2 " defer > </ script >
<!-- this uses the static value in a script tag -->
< script src =" @HtmxAntiforgeryScriptEndpoints.Path " defer > </ script >
</ head >
Copyright © 2022 Khalid Abuhakmeh
Por el presente se otorga permiso, sin cargo, a cualquier persona que obtenga una copia de este software y los archivos de documentación asociados (el "Software"), para operar con el Software sin restricciones, incluidos, entre otros, los derechos de uso, copia, modificación, fusión. , publicar, distribuir, sublicenciar y/o vender copias del Software, y permitir que las personas a quienes se les proporciona el Software lo hagan, sujeto a las siguientes condiciones:
El aviso de derechos de autor anterior y este aviso de permiso se incluirán en todas las copias o partes sustanciales del Software.
EL SOFTWARE SE PROPORCIONA “TAL CUAL”, SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO, ENTRE OTRAS, LAS GARANTÍAS DE COMERCIABILIDAD, IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGÚN RECLAMO, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, AGRAVIO O DE OTRA MANERA, QUE SURJA DE, FUERA DE O EN RELACIÓN CON EL SOFTWARE O EL USO U OTRAS NEGOCIOS EN EL SOFTWARE.