นี่เป็นแพ็คเกจที่ออกแบบมาเพื่อเพิ่มวิธีการช่วยเหลือฝั่งเซิร์ฟเวอร์สำหรับ HttpRequest
และ HttpResponse
ซึ่งทำให้การทำงานกับแนวคิดฝั่งเซิร์ฟเวอร์ htmx ง่ายขึ้น คุณควรพิจารณาอ่านเกี่ยวกับ Hyperscript ซึ่งเป็นโครงการเสริมสำหรับ HTMX
หากคุณยังใหม่กับ HTMX ลองดูซีรี่ส์นี้เกี่ยวกับการเริ่มต้นใช้งาน HTMX สำหรับนักพัฒนา ASP.NET Core ซึ่งรวมถึงโปรเจ็กต์ตัวอย่างและรูปแบบที่คุณอาจพบว่ามีประโยชน์
ติดตั้งแพ็คเกจ Htmx
NuGet ในโครงการ ASP.NET Core ของคุณ
dotnet add package Htmx
การใช้ HttpRequest
ทำให้เราสามารถระบุได้ว่าคำขอนั้นเริ่มต้นโดย Htmx บนไคลเอนต์หรือไม่
httpContext . Request . IsHtmx ( )
ซึ่งสามารถใช้เพื่อส่งคืนการตอบกลับแบบเต็มหน้าหรือการแสดงผลหน้าบางส่วน
// in a Razor Page
return Request . IsHtmx ( )
? Partial ( " _Form " , this )
: Page ( ) ;
นอกจากนี้เรายังสามารถดึงค่าส่วนหัวอื่น ๆ ที่ htmx อาจตั้งไว้ได้
Request . IsHtmx ( out var values ) ;
อ่านเพิ่มเติมเกี่ยวกับค่าส่วนหัวอื่นๆ ในหน้าเอกสารอย่างเป็นทางการ
โปรดทราบว่าหากเซิร์ฟเวอร์ของคุณสามารถแสดงเนื้อหาที่แตกต่างกันสำหรับ URL เดียวกันโดยขึ้นอยู่กับส่วนหัวอื่น คุณจะต้องใช้ส่วนหัว HTTP การตอบสนอง Vary ตัวอย่างเช่น หากเซิร์ฟเวอร์ของคุณแสดงผล HTML แบบเต็มเมื่อ Request.IsHtmx() เป็นเท็จ และแสดงผลส่วนของ HTML นั้นเมื่อ Request.IsHtmx() เป็นจริง คุณจะต้องเพิ่ม Vary: HX-Request ซึ่งทำให้แคชถูกคีย์โดยยึดตามส่วนประกอบของ URL ตอบกลับและส่วนหัวคำขอ HX แทนที่จะยึดตาม URL ตอบกลับเท่านั้น
// in a Razor Page
if ( Request . IsHtmx ( ) )
{
Response . Headers . Add ( " Vary " , " HX-Request " ) ;
return Partial ( " _Form " , this )
}
return Page ( ) ;
เราสามารถตั้งค่าส่วนหัว Http Response โดยใช้วิธีการขยาย Htmx
ซึ่งส่งผ่านการดำเนินการและวัตถุ HtmxResponseHeaders
Response . Htmx ( h => {
h . PushUrl ( " /new-url " )
. WithTrigger ( " cool " )
} ) ;
อ่านเพิ่มเติมเกี่ยวกับส่วนหัวการตอบสนอง HTTP ได้ที่เว็บไซต์เอกสารอย่างเป็นทางการ
คุณสามารถทริกเกอร์เหตุการณ์ฝั่งไคลเอ็นต์ด้วย HTMX ได้โดยใช้ส่วนหัว HX-Trigger
Htmx.Net มีวิธีการช่วยเหลือ WithTrigger
เพื่อกำหนดค่าเหตุการณ์หนึ่งเหตุการณ์ขึ้นไปที่คุณต้องการทริกเกอร์
Response . Htmx ( h => {
h . WithTrigger ( " yes " )
. WithTrigger ( " cool " , timing : HtmxTriggerTiming . AfterSettle )
. WithTrigger ( " neat " , new { valueForFrontEnd = 42 , status = " Done! " } , timing : HtmxTriggerTiming . AfterSwap ) ;
} ) ;
ตามค่าเริ่มต้น คำขอและการตอบกลับ Htmx ทั้งหมดจะถูกบล็อกในบริบทข้ามต้นทาง
หากคุณกำหนดค่าแอปพลิเคชันของคุณในบริบทแบบข้ามต้นทาง การตั้งค่านโยบาย CORS ใน ASP.NET Core ยังช่วยให้คุณสามารถกำหนดข้อจำกัดเฉพาะเกี่ยวกับคำขอและส่วนหัวการตอบกลับ ทำให้สามารถควบคุมข้อมูลที่สามารถแลกเปลี่ยนระหว่างเว็บของคุณได้อย่างละเอียด การประยุกต์ใช้และต้นกำเนิดที่แตกต่างกัน
ไลบรารีนี้มีวิธีง่ายๆ ในการเปิดเผยส่วนหัว Htmx ให้กับนโยบาย 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
} ) ;
} ) ;
ติดตั้งแพ็คเกจ Htmx.TagHelpers
NuGet ในโครงการ ASP.NET Core ของคุณ กำหนดเป้าหมายโปรเจ็กต์ .NET Core 3.1+
dotnet add package Htmx.TagHelpers
ทำให้ Tag Helpers พร้อมใช้งานในโครงการของคุณโดยเพิ่มบรรทัดต่อไปนี้ใน _ViewImports.cshtml
:
@addTagHelper *, Htmx.TagHelpers
โดยทั่วไปคุณจะต้องมีเส้นทาง URL ที่ชี้กลับไปยังแบ็กเอนด์ ASP.NET Core ของคุณ โชคดีที่ Htmx.TagHelpers
เลียนแบบการสร้าง URL ที่รวมอยู่ใน ASP.NET Core ซึ่งจะทำให้การเชื่อมโยง HTMX กับแอปพลิเคชัน ASP.NET Core ของคุณเป็นประสบการณ์ที่ราบรื่น
< 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 >
มีตัวช่วยแท็ก htmx-config
เพิ่มเติมที่สามารถนำไปใช้กับองค์ประกอบ meta
ใน head
ของเพจของคุณ ซึ่งทำให้การสร้างการกำหนดค่า HTMX ง่ายขึ้น ตัวอย่างเช่น ด้านล่างนี้เราสามารถตั้ง historyCacheSize
, default indicatorClass
และจะรวมโทเค็นป้องกันการปลอมแปลงของ ASP.NET Core เป็นองค์ประกอบเพิ่มเติมในการกำหนดค่า HTMX หรือไม่
<!DOCTYPE html >
< html lang =" en " >
< head >
< meta name =" htmx-config "
historyCacheSize =" 20 "
indicatorClass =" htmx-indicator "
includeAspNetAntiforgeryToken =" true "
/>
<!-- additional elements... -->
</ head >
HTML ที่ได้จะเป็น
<!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 >
คุณสามารถตั้งค่าแอตทริบิวต์ includeAspNetAntiforgerToken
บนองค์ประกอบ htmx-config
จากนั้น คุณจะต้องรวม JavaScript เพิ่มเติมนี้ไว้ในเว็บแอปพลิเคชันของคุณ เรารวมแอตทริบิวต์ __htmx_antiforgery
เพื่อติดตามว่ามีการเพิ่มผู้ฟังเหตุการณ์แล้ว สิ่งนี้จะทำให้เราไม่สามารถลงทะเบียน Listener เหตุการณ์อีกครั้งโดยไม่ตั้งใจ
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 ;
}
คุณสามารถเข้าถึงข้อมูลโค้ดได้สองวิธี สิ่งแรกคือการใช้คลาสคงที่ HtmxSnippet
ในมุมมองของคุณ
<script>
@Html.Raw(HtmxSnippets.AntiforgeryJavaScript)
</script>
วิธีที่ง่ายกว่าคือการใช้คลาส HtmlExtensions
ที่ขยาย IHtmlHelper
@Html.HtmxAntiforgeryScript()
ตัวช่วย html นี้จะส่งผลให้มีแท็ก <script>
พร้อมกับ JavaScript ที่กล่าวถึงก่อนหน้านี้ หมายเหตุ: คุณยังคงสามารถลงทะเบียนตัวจัดการเหตุการณ์หลายตัวสำหรับ htmx:configRequest
ได้ ดังนั้นการมีมากกว่าหนึ่งตัวก็เป็นเรื่องปกติ
โปรดทราบว่าหากแอตทริบิวต์ hx-[get|post|put]
อยู่บนแท็ก <form ..>
และ องค์ประกอบ <form>
มี method="post"
(และยังมีแอตทริบิวต์ action=""
ที่ว่างเปล่าหรือหายไปด้วย) ตัวช่วยแท็ก ASP.NET จะเพิ่มโทเค็นต่อต้านการปลอมแปลงเป็นองค์ประกอบ input
และคุณไม่จำเป็นต้องกำหนดค่าคำขอของคุณเพิ่มเติมดังที่กล่าวข้างต้น คุณยังสามารถใช้ hx-include
ชี้ไปที่แบบฟอร์มได้ แต่ทั้งหมดนี้ขึ้นอยู่กับความชอบของคุณ
นอกจากนี้ แนวทางที่แนะนำ คือใช้ HtmxAntiforgeryScriptEndpoint
ซึ่งจะช่วยให้คุณสามารถแมปไฟล์ JavaScript กับตำแหน่งข้อมูลเฉพาะได้ และตามค่าเริ่มต้นจะเป็น _htmx/antiforgery.js
app . UseAuthorization ( ) ;
// registered here
app . MapHtmxAntiforgeryScript ( ) ;
app . MapRazorPages ( ) ;
app . MapControllers ( ) ;
ตอนนี้คุณสามารถกำหนดค่าตำแหน่งข้อมูลนี้ด้วยการแคช การรับรองความถูกต้อง ฯลฯ ที่สำคัญกว่านั้น คุณสามารถใช้สคริปต์ในแท็ก head
ของคุณได้ทันทีโดยใช้แท็ก defer
ซึ่งต้องการให้มี JavaScript ที่ส่วนท้ายขององค์ประกอบ 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 >
ลิขสิทธิ์ © 2022 คาลิด อบูฮักเมห์
อนุญาตให้บุคคลใดๆ ได้รับสำเนาของซอฟต์แวร์นี้และไฟล์เอกสารที่เกี่ยวข้อง (“ซอฟต์แวร์”) โดยไม่เสียค่าใช้จ่าย เพื่อจัดการกับซอฟต์แวร์โดยไม่มีข้อจำกัด รวมถึงแต่ไม่จำกัดเพียงสิทธิ์ในการใช้ คัดลอก ปรับเปลี่ยน ผสาน เผยแพร่ แจกจ่าย ให้อนุญาตช่วง และ/หรือขายสำเนาของซอฟต์แวร์ และอนุญาตให้บุคคลที่ได้รับซอฟต์แวร์นี้สามารถทำได้ ภายใต้เงื่อนไขต่อไปนี้:
ประกาศเกี่ยวกับลิขสิทธิ์ข้างต้นและประกาศการอนุญาตนี้จะรวมอยู่ในสำเนาทั้งหมดหรือส่วนสำคัญของซอฟต์แวร์
ซอฟต์แวร์นี้มีให้ "ตามที่เป็น" โดยไม่มีการรับประกันใดๆ ทั้งโดยชัดแจ้งหรือโดยนัย ซึ่งรวมถึงแต่ไม่จำกัดเพียงการรับประกันความสามารถในการค้าขาย ความเหมาะสมสำหรับวัตถุประสงค์เฉพาะ และการไม่ละเมิด ไม่ว่าในกรณีใดผู้เขียนหรือผู้ถือลิขสิทธิ์จะต้องรับผิดต่อการเรียกร้องค่าเสียหายหรือความรับผิดอื่นใดไม่ว่าในการกระทำของสัญญาการละเมิดหรืออย่างอื่นที่เกิดขึ้นจากหรือเกี่ยวข้องกับซอฟต์แวร์หรือการใช้งานหรือข้อตกลงอื่น ๆ ใน ซอฟต์แวร์.