htmx

hx-get 与 hx-post 基础请求

By AI-Writer 5 min read

hx-get 与 hx-post 基础请求

htmx 的核心能力在于让 HTML 元素直接发起 HTTP 请求。本文将深入讲解 hx-gethx-post 以及相关的请求控制属性,帮助你掌握 htmx 最基础也是最常用的交互模式。

hx-get:获取数据

hx-get 是最常用的 htmx 属性,它让元素在被触发时向指定 URL 发起 GET 请求。

基础用法

html
<div hx-get="/api/user-info">
    点击加载用户信息
</div>

默认情况下,hx-get 在元素的 click 事件上触发。点击 div 后,htmx 会向 /api/user-info 发起 GET 请求,并将返回的 HTML 替换该 div 的内容。

链接的渐进增强

html
<a href="/profile" hx-get="/profile" hx-target="#content">
    查看个人资料
</a>

这个链接同时具有传统 hrefhx-get。如果 htmx 未加载,点击会正常跳转;如果 htmx 已加载,则只更新 #content 区域。

带查询参数

html
<input type="search"
       name="q"
       hx-get="/api/search"
       hx-trigger="keyup changed delay:500ms"
       hx-target="#search-results" />

输入框的值会自动作为查询参数附加到 URL:/api/search?q=用户输入

提示:htmx 会自动收集带有 name 属性的表单元素的值,作为请求参数发送。

hx-post:提交数据

hx-post 用于向服务器提交数据,通常配合表单使用。

基础表单提交

html
<form hx-post="/api/login" hx-target="#message">
    <input type="email" name="email" placeholder="邮箱" required />
    <input type="password" name="password" placeholder="密码" required />
    <button type="submit">登录</button>
</form>
<div id="message"></div>

表单提交时,htmx 会自动序列化所有表单字段的值,以 application/x-www-form-urlencoded 格式发送 POST 请求。服务器返回的 HTML 将替换 #message 的内容。

非表单元素的 POST

html
<button hx-post="/api/like/42"
        hx-target="this"
        hx-swap="outerHTML">
    ❤️ 点赞
</button>

任何元素都可以使用 hx-post。上例中,点击按钮向 /api/like/42 发送 POST 请求,然后用返回的 HTML 替换按钮本身(可能变为”已点赞”状态)。

文件上传

html
<form hx-post="/api/upload"
      hx-encoding="multipart/form-data"
      hx-target="#upload-status">
    <input type="file" name="document" />
    <button type="submit">上传</button>
</form>
<div id="upload-status"></div>

上传文件时需要显式设置 hx-encoding="multipart/form-data",htmx 会自动处理 FormData 的构建和发送。

注意:htmx 2.x 支持文件上传的进度事件,可以通过 htmx:xhr:progress 事件监听上传进度。

其他 HTTP 方法

htmx 支持完整的 RESTful HTTP 方法集合:

html
<!-- PUT:完整更新资源 -->
<button hx-put="/api/users/123" hx-include="#edit-form">
    保存修改
</button>

<!-- DELETE:删除资源 -->
<button hx-delete="/api/posts/456"
        hx-confirm="确定要删除这篇文章吗?"
        hx-target="closest article"
        hx-swap="delete">
    删除
</button>

<!-- PATCH:部分更新 -->
<form hx-patch="/api/settings">
    <input type="checkbox" name="notifications" checked />
    <button type="submit">更新设置</button>
</form>
属性用途幂等性
hx-get获取资源幂等
hx-post创建资源/提交数据非幂等
hx-put完整替换资源幂等
hx-patch部分更新资源非幂等
hx-delete删除资源幂等

请求指示器

当网络请求需要时间时,给用户反馈至关重要。htmx 通过 hx-indicator 属性提供了优雅的加载状态显示机制。

基础指示器

html
<button hx-get="/api/slow-data" hx-indicator="#loading">
    加载数据
</button>
<div id="loading" class="htmx-indicator">
    加载中...
</div>

.htmx-indicator 是一个特殊的 CSS 类。htmx 在请求期间自动为匹配的元素添加 .htmx-request 类,你可以利用这个类控制指示器的显示:

css
.htmx-indicator {
    display: none;
}
.htmx-request .htmx-indicator,
.htmx-indicator.htmx-request {
    display: inline;
}

使用 CSS 动画

html
<button hx-post="/api/generate" hx-indicator=".spinner">
    生成报告
</button>
<span class="spinner htmx-indicator">⏳</span>

更现代化的做法是使用 CSS 动画:

css
.htmx-indicator {
    opacity: 0;
    transition: opacity 200ms;
}
.htmx-request .htmx-indicator,
.htmx-indicator.htmx-request {
    opacity: 1;
}

在触发元素上显示状态

html
<button hx-get="/api/data"
        hx-indicator="this"
        class="btn">
    获取数据
</button>

hx-indicator="this" 表示在请求期间,按钮本身会获得 .htmx-request 类。你可以用它改变按钮样式:

css
.btn.htmx-request {
    opacity: 0.6;
    cursor: wait;
}

包含额外数据

hx-include

有时候需要包含当前元素之外的表单数据:

html
<form id="filter-form">
    <input type="text" name="category" />
    <input type="number" name="min-price" />
</form>

<button hx-get="/api/products"
        hx-include="#filter-form"
        hx-target="#product-list">
    筛选商品
</button>

hx-include 会将 #filter-form 中所有字段的值包含到请求中。

hx-vals

添加额外的静态或动态值:

html
<button hx-post="/api/vote"
        hx-vals='{"candidate": "alice", "round": 3}'
        hx-target="#result">
    投票给 Alice
</button>

也可以动态计算值:

html
<button hx-post="/api/track"
        hx-vals="js:{timestamp: Date.now(), path: window.location.pathname}">
    记录事件
</button>

js: 前缀表示后面的内容是 JavaScript 表达式,在请求时动态求值。

请求头控制

hx-headers

自定义请求头:

html
<button hx-get="/api/protected"
        hx-headers='{"X-API-Key": "secret123"}'
        hx-target="#data">
    获取受保护数据
</button>

内容协商

htmx 默认在请求头中发送 HX-Request: true,让服务器识别这是一个 htmx AJAX 请求:

python
# Flask 示例:根据请求类型返回不同内容
from flask import request, render_template

@app.route('/profile')
def profile():
    user = get_current_user()
    if request.headers.get('HX-Request'):
        # htmx 请求:返回 HTML 片段
        return render_template('profile_partial.html', user=user)
    # 普通请求:返回完整页面
    return render_template('profile.html', user=user)

这是 htmx 应用的经典模式:同一个路由,根据 HX-Request 头返回完整页面或局部片段

错误处理

hx-confirm

在发送请求前弹出确认对话框:

html
<button hx-delete="/api/account"
        hx-confirm="此操作不可撤销,确定要删除账户吗?"
        hx-target="body">
    删除账户
</button>

监听错误事件

javascript
document.body.addEventListener('htmx:response-error', function(evt) {
    const xhr = evt.detail.xhr;
    console.error('请求失败:', xhr.status, xhr.statusText);
    alert('请求失败: ' + xhr.statusText);
});

document.body.addEventListener('htmx:send-error', function(evt) {
    console.error('网络错误,无法连接到服务器');
});

服务端错误响应

服务端返回非 2xx 状态码时,htmx 会触发错误事件。你也可以返回带有错误信息的 HTML 片段:

python
@app.route('/api/login', methods=['POST'])
def login():
    email = request.form.get('email')
    password = request.form.get('password')

    if not validate_user(email, password):
        return '<div class="error">邮箱或密码错误</div>', 401

    return '<div class="success">登录成功!</div>'

完整示例:评论系统

html
<div id="comments">
    <div class="comment">第一条评论</div>
</div>

<form hx-post="/api/comments"
      hx-target="#comments"
      hx-swap="beforeend"
      hx-indicator="#comment-spinner"
      hx-on::after-request="this.reset()">
    <textarea name="content" required placeholder="写下你的评论..."></textarea>
    <button type="submit">
        发表评论
        <span id="comment-spinner" class="htmx-indicator">...</span>
    </button>
</form>

这个表单演示了多个属性的协同工作:

  • hx-post — 提交评论到 /api/comments
  • hx-target + hx-swap="beforeend" — 将新评论追加到列表末尾
  • hx-indicator — 显示加载状态
  • hx-on::after-request — 请求成功后清空表单

总结

本文涵盖了 htmx 请求发起的基础知识:

  • hx-get — 获取数据,适合加载内容和搜索场景
  • hx-post — 提交数据,是表单交互的主力
  • hx-put/hx-patch/hx-delete — 完整的 RESTful 方法支持
  • hx-indicator — 请求期间的状态反馈机制
  • hx-include/hx-vals — 灵活控制请求数据
  • HX-Request 请求头 — 服务端识别 htmx 请求的经典模式

掌握这些属性后,你已经能够构建大部分常见的 AJAX 交互场景。下一篇文章将深入探讨 目标元素与内容交换策略,理解 hx-targethx-swap 的完整能力。

#htmx #ajax #hx-get #hx-post #http

评论

A

Written by

AI-Writer

Related Articles

htmx
#4

触发器与修饰符

深入掌握 hx-trigger 的完整语法体系,学习事件类型、过滤器、延迟、轮询、可见性触发及各种修饰符的使用场景

Read More
htmx
#2

hx-get 与 hx-post 基础请求

深入掌握 htmx 的基本 HTTP 请求属性,学习如何通过声明式 hx-get、hx-post 发起异步请求,以及请求指示器和错误处理机制

Read More