Il s'agit d'un package conçu pour ajouter des méthodes d'assistance côté serveur pour HttpRequest
et HttpResponse
. Cela simplifie le travail avec les concepts côté serveur HTML. Vous devriez également envisager de lire sur Hyperscript, un projet compagnon facultatif pour HTMX.
Si vous êtes nouveau sur HTMX, consultez cette série sur la prise en main de HTMX pour les développeurs ASP.NET Core, qui comprend également un exemple de projet et des modèles qui pourraient vous être utiles.
Installez le package Htmx
NuGet sur votre projet ASP.NET Core.
dotnet add package Htmx
En utilisant le HttpRequest
, nous pouvons déterminer si la requête a été initiée par Htmx sur le client.
httpContext . Request . IsHtmx ( )
Cela peut être utilisé pour renvoyer une réponse complète ou un rendu de page partiel.
// in a Razor Page
return Request . IsHtmx ( )
? Partial ( " _Form " , this )
: Page ( ) ;
Nous pouvons également récupérer les autres valeurs d’en-tête que htmx pourrait définir.
Request . IsHtmx ( out var values ) ;
En savoir plus sur les autres valeurs d'en-tête sur la page de documentation officielle.
En particulier, n'oubliez pas que si votre serveur peut afficher un contenu différent pour la même URL en fonction d'autres en-têtes, vous devez utiliser l'en-tête HTTP de réponse Vary. Par exemple, si votre serveur restitue le code HTML complet lorsque Request.IsHtmx() est faux et qu'il restitue un fragment de ce code HTML lorsque Request.IsHtmx() est vrai, vous devez ajouter Vary : HX-Request. Cela entraîne la saisie du cache en fonction d'un composite de l'URL de réponse et de l'en-tête de requête HX-Request, plutôt que d'être basé uniquement sur l'URL de réponse.
// in a Razor Page
if ( Request . IsHtmx ( ) )
{
Response . Headers . Add ( " Vary " , " HX-Request " ) ;
return Partial ( " _Form " , this )
}
return Page ( ) ;
Nous pouvons définir les en-têtes de réponse Http à l'aide de la méthode d'extension Htmx
, qui transmet une action et un objet HtmxResponseHeaders
.
Response . Htmx ( h => {
h . PushUrl ( " /new-url " )
. WithTrigger ( " cool " )
} ) ;
En savoir plus sur les en-têtes de réponse HTTP sur le site de documentation officiel.
Vous pouvez déclencher des événements côté client avec HTMX à l'aide de l'en-tête HX-Trigger
. Htmx.Net fournit une méthode d'assistance WithTrigger
pour configurer un ou plusieurs événements que vous souhaitez déclencher.
Response . Htmx ( h => {
h . WithTrigger ( " yes " )
. WithTrigger ( " cool " , timing : HtmxTriggerTiming . AfterSettle )
. WithTrigger ( " neat " , new { valueForFrontEnd = 42 , status = " Done! " } , timing : HtmxTriggerTiming . AfterSwap ) ;
} ) ;
Par défaut, toutes les requêtes et réponses Htmx seront bloquées dans un contexte cross-origin.
Si vous configurez votre application dans un contexte multi-origine, la définition d'une stratégie CORS dans ASP.NET Core vous permet également de définir des restrictions spécifiques sur les en-têtes de requête et de réponse, permettant un contrôle précis sur les données qui peuvent être échangées entre vos applications Web. application et origines différentes.
Cette bibliothèque fournit une approche simple pour exposer les en-têtes Htmx à votre stratégie 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
} ) ;
} ) ;
Installez le package NuGet Htmx.TagHelpers
sur votre projet ASP.NET Core. Cible les projets .NET Core 3.1+.
dotnet add package Htmx.TagHelpers
Rendez les Tag Helpers disponibles dans votre projet en ajoutant la ligne suivante à votre _ViewImports.cshtml
:
@addTagHelper *, Htmx.TagHelpers
Vous aurez généralement besoin de chemins d’URL pointant vers votre backend ASP.NET Core. Heureusement, Htmx.TagHelpers
imite la génération d'URL incluse dans ASP.NET Core. Cela fait de la liaison HTMX avec votre application ASP.NET Core une expérience transparente.
< 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 >
Un assistant de balise htmx-config
supplémentaire est inclus et peut être appliqué à un élément meta
dans head
de votre page, ce qui simplifie la création de la configuration HTMX. Par exemple, ci-dessous, nous pouvons définir le historyCacheSize
, indicatorClass
par défaut et l'inclusion ou non des jetons anti-contrefaçon d'ASP.NET Core en tant qu'élément supplémentaire dans la configuration HTMX.
<!DOCTYPE html >
< html lang =" en " >
< head >
< meta name =" htmx-config "
historyCacheSize =" 20 "
indicatorClass =" htmx-indicator "
includeAspNetAntiforgeryToken =" true "
/>
<!-- additional elements... -->
</ head >
Le HTML résultant sera.
<!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 >
Vous pouvez définir l'attribut includeAspNetAntiforgerToken
sur l'élément htmx-config
. Ensuite, vous devrez inclure ce JavaScript supplémentaire dans votre application Web. Nous incluons l'attribut __htmx_antiforgery
pour suivre l'écouteur d'événement qui a déjà été ajouté. Cela nous évite de réenregistrer accidentellement l'écouteur d'événement.
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 ;
}
Vous pouvez accéder à l'extrait de deux manières. La première consiste à utiliser la classe statique HtmxSnippet
dans vos vues.
<script>
@Html.Raw(HtmxSnippets.AntiforgeryJavaScript)
</script>
Un moyen plus simple consiste à utiliser la classe HtmlExtensions
qui étend IHtmlHelper
.
@Html.HtmxAntiforgeryScript()
Cet assistant HTML se traduira par une balise <script>
avec le JavaScript mentionné précédemment. Remarque : Vous pouvez toujours enregistrer plusieurs gestionnaires d'événements pour htmx:configRequest
, donc en avoir plusieurs est acceptable.
Notez que si l'attribut hx-[get|post|put]
est sur une balise <form ..>
et que l'élément <form>
a un attribut method="post"
(et également un action=""
vide ou manquant), les ASP.NET Tag Helpers ajouteront le jeton anti-contrefaçon comme élément input
et vous n'aurez pas besoin de configurer davantage vos demandes comme ci-dessus. Vous pouvez également utiliser hx-include
pointant vers un formulaire, mais tout cela se résume à une question de préférence.
De plus, l'approche recommandée consiste à utiliser HtmxAntiforgeryScriptEndpoint
, qui vous permettra de mapper le fichier JavaScript à un point de terminaison spécifique, et par défaut ce sera _htmx/antiforgery.js
.
app . UseAuthorization ( ) ;
// registered here
app . MapHtmxAntiforgeryScript ( ) ;
app . MapRazorPages ( ) ;
app . MapControllers ( ) ;
Vous pouvez maintenant configurer ce point de terminaison avec la mise en cache, l'authentification, etc. Plus important encore, vous pouvez maintenant utiliser le script dans votre balise head
en appliquant la balise defer
, qui est préférable à avoir JavaScript à la fin d'un élément 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
L'autorisation est par la présente accordée, gratuitement, à toute personne obtenant une copie de ce logiciel et des fichiers de documentation associés (le « Logiciel »), d'utiliser le Logiciel sans restriction, y compris, sans limitation, les droits d'utilisation, de copie, de modification, de fusion. , publier, distribuer, accorder des sous-licences et/ou vendre des copies du Logiciel, et permettre aux personnes à qui le Logiciel est fourni de le faire, sous réserve des conditions suivantes :
L'avis de droit d'auteur ci-dessus et cet avis d'autorisation doivent être inclus dans toutes les copies ou parties substantielles du logiciel.
LE LOGICIEL EST FOURNI « TEL QUEL », SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS MAIS SANS LIMITATION LES GARANTIES DE QUALITÉ MARCHANDE, D'ADAPTATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS OU LES TITULAIRES DES DROITS D'AUTEUR NE SERONT RESPONSABLES DE TOUTE RÉCLAMATION, DOMMAGES OU AUTRE RESPONSABILITÉ, QUE CE SOIT DANS UNE ACTION CONTRACTUELLE, DÉLIT OU AUTRE, DÉCOULANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRANSACTIONS DANS LE LOGICIEL.