You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法通过htmx的hx-put在Flask视图中读取hx-include的值

解决htmx PUT请求传递select值到Flask的415错误问题

问题现象

通过htmx的hx-put提交模态框内select元素的值到Flask视图函数时,后端用request.get_json()无法获取数据,控制台出现以下错误:

SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
    at JSON.parse (<anonymous>)
    at S (htmx.min.js:1:4795)
    at dr (htmx.min.js:1:34354)
    at sr (htmx.min.js:1:31612)
    at ce (htmx.min.js:1:37724)
    at htmx.min.js:1:21402
    at HTMLButtonElement.i (htmx.min.js:1:17838)
y @ htmx.min.js:1
S @ htmx.min.js:1
dr @ htmx.min.js:1
sr @ htmx.min.js:1
ce @ htmx.min.js:1
(anonymous) @ htmx.min.js:1
i @ htmx.min.js:1
htmx.min.js:1 

  PUT http://localhost:5000/lot/update_storage/1 415 (UNSUPPORTED MEDIA TYPE)
ce @ htmx.min.js:1
(anonymous) @ htmx.min.js:1
i @ htmx.min.js:1
htmx.min.js:1 Response Status Error Code 415 from /lot/update_storage/1

相关代码如下:

HTML代码

<div class="modal-dialog modal-dialog-centered">
  <div class="modal-content">
    <div class="modal-header">
      <h5 id="muctor" class="modal-title">{{ title }}</h5>
      <h5  class="modal-title">{{ title }}</h5>
    </div>
    <div class="modal-body">
      <div class="dropdown">
          <select id="selected_storage" name="pavvy" class="form-select form-select-sm" aria-label=".form-select-sm example">
              {% for i in items %}
                <option value="{{ i.id }}">{{ i.name }}</option>
              {% endfor %}
            </select>
        </div>
    </div>
  <div><input type="text" id="username" placeholder="Enter your name"></div>
    <div class="modal-footer">
      <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      <button 
        type="button"
        hx-put="{{ url_for('lots_bp.update_storage', id=id) }}"
        hx-include="#selected_storage"
        hx-swap="none"
        hx-headers="{'Content-Type': 'application/json'}"
        hx-trigger="click"
        class="btn btn-sm btn-primary">Submit</button>
    </div>
  </div>
</div>

Python代码

@lots_bp.route("/update_storage/<int:id>", methods=["PUT"])
def update_storage(id: int):
    print(request.get_json())
    return ""

错误原因

手动设置了hx-headers="{'Content-Type': 'application/json'}",但htmx通过hx-include收集的表单元素数据默认是以application/x-www-form-urlencoded格式发送的,并非JSON格式。这就导致两个问题:

  1. Flask后端收到非JSON格式的数据,用request.get_json()无法解析,返回415不支持的媒体类型。
  2. htmx前端收到后端的错误响应后,尝试将其解析为JSON,进而触发JSON语法错误。

解决方案

方案一:移除JSON头部,使用表单格式接收(推荐)

这种方法更贴合htmx默认的表单数据处理逻辑,无需额外构造JSON:

  1. 修改HTML中的提交按钮,移除hx-headers属性:
<button 
  type="button"
  hx-put="{{ url_for('lots_bp.update_storage', id=id) }}"
  hx-include="#selected_storage"
  hx-swap="none"
  hx-trigger="click"
  class="btn btn-sm btn-primary">Submit</button>
  1. 修改Flask视图函数,通过request.form获取表单数据(select的name属性为pavvy):
@lots_bp.route("/update_storage/<int:id>", methods=["PUT"])
def update_storage(id: int):
    selected_storage_id = request.form.get('pavvy')
    print(selected_storage_id)
    return ""

方案二:构造JSON格式数据发送

如果确实需要发送JSON格式数据,可以通过hx-vals手动构造JSON内容,同时保留正确的请求头:

  1. 修改HTML提交按钮,用hx-vals指定JSON数据,注意引号使用(外层用单引号,内层用双引号):
<button 
  type="button"
  hx-put="{{ url_for('lots_bp.update_storage', id=id) }}"
  hx-vals='{"pavvy": document.getElementById("selected_storage").value}'
  hx-headers='{"Content-Type": "application/json"}'
  hx-swap="none"
  hx-trigger="click"
  class="btn btn-sm btn-primary">Submit</button>
  1. Flask视图函数可以继续使用request.get_json()获取数据:
@lots_bp.route("/update_storage/<int:id>", methods=["PUT"])
def update_storage(id: int):
    data = request.get_json()
    print(data.get('pavvy'))
    return ""

内容的提问来源于stack exchange,提问作者godhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:02:04