Ini adalah paket yang dirancang untuk menambahkan metode pembantu sisi server untuk HttpRequest
dan HttpResponse
. Hal ini membuat bekerja dengan konsep sisi server htmx menjadi lebih sederhana. Anda juga harus mempertimbangkan membaca tentang Hyperscript, proyek pendamping opsional untuk HTML.
Jika Anda baru mengenal HTMX, lihat seri ini tentang cara memulai HTMX untuk pengembang ASP.NET Core yang juga menyertakan contoh proyek dan pola yang mungkin berguna bagi Anda.
Instal paket Htmx
NuGet ke proyek ASP.NET Core Anda.
dotnet add package Htmx
Dengan menggunakan HttpRequest
, kita dapat menentukan apakah permintaan tersebut dimulai oleh Htmx pada klien.
httpContext . Request . IsHtmx ( )
Ini dapat digunakan untuk mengembalikan respons halaman penuh atau render halaman sebagian.
// in a Razor Page
return Request . IsHtmx ( )
? Partial ( " _Form " , this )
: Page ( ) ;
Kami juga dapat mengambil nilai header lain yang mungkin disetel htmx.
Request . IsHtmx ( out var values ) ;
Baca selengkapnya tentang nilai header lainnya di halaman dokumentasi resmi.
Sebagai catatan khusus, harap diingat bahwa jika server Anda dapat merender konten berbeda untuk URL yang sama bergantung pada beberapa header lainnya, Anda perlu menggunakan header HTTP respons Vary. Misalnya, jika server Anda merender HTML lengkap saat Request.IsHtmx() salah, dan server merender sebagian HTML tersebut saat Request.IsHtmx() benar, Anda perlu menambahkan Vary: HX-Request. Hal ini menyebabkan cache dikunci berdasarkan gabungan URL respons dan header permintaan HX-Request — bukan hanya didasarkan pada URL respons.
// in a Razor Page
if ( Request . IsHtmx ( ) )
{
Response . Headers . Add ( " Vary " , " HX-Request " ) ;
return Partial ( " _Form " , this )
}
return Page ( ) ;
Kita dapat menyetel header Respons Http menggunakan metode ekstensi Htmx
, yang meneruskan tindakan dan objek HtmxResponseHeaders
.
Response . Htmx ( h => {
h . PushUrl ( " /new-url " )
. WithTrigger ( " cool " )
} ) ;
Baca selengkapnya tentang header respons HTTP di situs dokumentasi resmi.
Anda dapat memicu peristiwa sisi klien dengan HTMX menggunakan header HX-Trigger
. Htmx.Net menyediakan metode pembantu WithTrigger
untuk mengonfigurasi satu atau lebih peristiwa yang ingin Anda picu.
Response . Htmx ( h => {
h . WithTrigger ( " yes " )
. WithTrigger ( " cool " , timing : HtmxTriggerTiming . AfterSettle )
. WithTrigger ( " neat " , new { valueForFrontEnd = 42 , status = " Done! " } , timing : HtmxTriggerTiming . AfterSwap ) ;
} ) ;
Secara default, semua permintaan dan tanggapan Htmx akan diblokir dalam konteks lintas asal.
Jika Anda mengonfigurasi aplikasi Anda dalam konteks lintas asal, maka menetapkan kebijakan CORS di ASP.NET Core juga memungkinkan Anda menentukan batasan spesifik pada header permintaan dan respons, sehingga memungkinkan kontrol menyeluruh atas data yang dapat dipertukarkan antar web Anda. aplikasi dan asal yang berbeda.
Pustaka ini menyediakan pendekatan sederhana untuk mengekspos header Htmx ke kebijakan CORS Anda:
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
} ) ;
} ) ;
Instal paket Htmx.TagHelpers
NuGet ke proyek ASP.NET Core Anda. Menargetkan proyek .NET Core 3.1+.
dotnet add package Htmx.TagHelpers
Jadikan Pembantu Tag tersedia di proyek Anda dengan menambahkan baris berikut ke _ViewImports.cshtml
:
@addTagHelper *, Htmx.TagHelpers
Biasanya Anda memerlukan jalur URL yang mengarah kembali ke backend ASP.NET Core Anda. Untungnya, Htmx.TagHelpers
meniru pembuatan url yang disertakan dalam ASP.NET Core. Hal ini membuat penautan HTMX dengan aplikasi ASP.NET Core Anda menjadi pengalaman yang mulus.
< 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 >
Pembantu tag htmx-config
tambahan disertakan yang dapat diterapkan ke elemen meta
di head
halaman Anda yang membuat pembuatan konfigurasi HTML lebih sederhana. Misalnya, di bawah ini kita dapat mengatur historyCacheSize
, default indicatorClass
, dan apakah akan menyertakan token anti-pemalsuan ASP.NET Core sebagai elemen tambahan pada konfigurasi HTMX.
<!DOCTYPE html >
< html lang =" en " >
< head >
< meta name =" htmx-config "
historyCacheSize =" 20 "
indicatorClass =" htmx-indicator "
includeAspNetAntiforgeryToken =" true "
/>
<!-- additional elements... -->
</ head >
HTML yang dihasilkan akan menjadi.
<!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 >
Anda dapat mengatur atribut includeAspNetAntiforgerToken
pada elemen htmx-config
. Maka Anda harus menyertakan JavaScript tambahan ini dalam aplikasi web Anda. Kami menyertakan atribut __htmx_antiforgery
untuk melacak pendengar acara yang telah ditambahkan. Hal ini mencegah kami mendaftarkan ulang pendengar acara secara tidak sengaja.
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 ;
}
Anda dapat mengakses cuplikan dengan dua cara. Yang pertama adalah menggunakan kelas statis HtmxSnippet
dalam tampilan Anda.
<script>
@Html.Raw(HtmxSnippets.AntiforgeryJavaScript)
</script>
Cara yang lebih sederhana adalah dengan menggunakan kelas HtmlExtensions
yang memperluas IHtmlHelper
.
@Html.HtmxAntiforgeryScript()
Pembantu html ini akan menghasilkan tag <script>
bersama dengan JavaScript yang disebutkan sebelumnya. Catatan: Anda masih dapat mendaftarkan beberapa event handler untuk htmx:configRequest
, jadi memiliki lebih dari satu tidak masalah.
Perhatikan bahwa jika atribut hx-[get|post|put]
ada pada tag <form ..>
dan elemen <form>
memiliki method="post"
(dan juga atribut action=""
) yang kosong atau hilang, Pembantu Tag ASP.NET akan menambahkan Token Anti-pemalsuan sebagai elemen input
dan Anda tidak perlu mengonfigurasi permintaan Anda lebih lanjut seperti di atas. Anda juga bisa menggunakan hx-include
untuk menunjuk ke suatu formulir, tetapi ini semua tergantung pada preferensi.
Selain itu, pendekatan yang disarankan adalah menggunakan HtmxAntiforgeryScriptEndpoint
, yang memungkinkan Anda memetakan file JavaScript ke titik akhir tertentu, dan secara default adalah _htmx/antiforgery.js
.
app . UseAuthorization ( ) ;
// registered here
app . MapHtmxAntiforgeryScript ( ) ;
app . MapRazorPages ( ) ;
app . MapControllers ( ) ;
Anda sekarang dapat mengonfigurasi titik akhir ini dengan caching, autentikasi, dll. Yang lebih penting, Anda dapat menggunakan skrip di tag head
Anda sekarang dengan menerapkan tag defer
, yang lebih disukai daripada memiliki JavaScript di akhir elemen 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 >
Hak Cipta © 2022 Khalid Abuhakmeh
Izin dengan ini diberikan, secara gratis, kepada siapa pun yang memperoleh salinan perangkat lunak ini dan file dokumentasi terkait (“Perangkat Lunak”), untuk menangani Perangkat Lunak tanpa batasan, termasuk namun tidak terbatas pada hak untuk menggunakan, menyalin, memodifikasi, menggabungkan , mempublikasikan, mendistribusikan, mensublisensikan, dan/atau menjual salinan Perangkat Lunak, dan mengizinkan orang yang menerima Perangkat Lunak untuk melakukan hal tersebut, dengan tunduk pada ketentuan berikut:
Pemberitahuan hak cipta di atas dan pemberitahuan izin ini akan disertakan dalam semua salinan atau sebagian besar Perangkat Lunak.
PERANGKAT LUNAK INI DISEDIAKAN “APA ADANYA”, TANPA JAMINAN APA PUN, TERSURAT MAUPUN TERSIRAT, TERMASUK NAMUN TIDAK TERBATAS PADA JAMINAN KELAYAKAN UNTUK DIPERDAGANGKAN, KESESUAIAN UNTUK TUJUAN TERTENTU, DAN TIDAK ADA PELANGGARAN. DALAM KEADAAN APA PUN PENULIS ATAU PEMEGANG HAK CIPTA TIDAK BERTANGGUNG JAWAB ATAS KLAIM, KERUSAKAN, ATAU TANGGUNG JAWAB LAINNYA, BAIK DALAM TINDAKAN KONTRAK, HUKUM ATAU LAINNYA, YANG TIMBUL DARI, ATAU SEHUBUNGAN DENGAN PERANGKAT LUNAK ATAU PENGGUNAAN ATAU HAL-HAL LAIN DALAM PERANGKAT LUNAK.