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

使用Compojure+htmx构建应用,POST请求/clicked返回403禁止访问

问题:Compojure 结合 htmx 点击按钮返回403状态码

我用Compojure和htmx写了一个简单的Hello World应用,代码如下:

(defroutes app-routes
  (GET "/" [] "
<html>
<script src=\"https://unpkg.com/htmx.org@1.9.8\"></script>
  <!-- have a button POST a click via AJAX -->
  <button hx-post=\"/clicked\" hx-swap=\"outerHTML\">
    Click Me
  </button>
</html>
")

  (POST "/clicked" [] "
<html>
<body>
Hello
</body>
</html>
")

点击按钮时,从/clicked接口收到htmx返回的403状态错误码,请问这是什么原因?


原因及解决方法

出现403错误的核心原因是Compojure默认启用了CSRF(跨站请求伪造)保护机制,而htmx发起的POST请求没有携带有效的CSRF令牌,因此被服务器拦截。

解决方法有两种:

1. 临时关闭CSRF保护(仅用于测试,不推荐生产环境)

在配置Compojure应用时,去掉CSRF中间件。如果使用ring-defaults,可以修改默认配置:

(def app
  (wrap-defaults app-routes (assoc site-defaults :security {:anti-forgery false})))

2. 正确传递CSRF令牌(推荐生产环境使用)

在返回的HTML页面中注入CSRF令牌,让htmx自动读取并携带:

  • 方式一:通过meta标签全局配置htmx请求头
(GET "/" request
  (let [csrf-token (:anti-forgery-token request)]
    (str "<html>
<script src=\"https://unpkg.com/htmx.org@1.9.8\"></script>
<meta name=\"htmx-config\" content='{\"headers\": {\"X-CSRF-Token\": \"" csrf-token "\"}}'>
<button hx-post=\"/clicked\" hx-swap=\"outerHTML\">
  Click Me
</button>
</html>")))
  • 方式二:通过按钮的hx-headers属性单独设置
(GET "/" request
  (let [csrf-token (:anti-forgery-token request)]
    (str "<html>
<script src=\"https://unpkg.com/htmx.org@1.9.8\"></script>
<button hx-post=\"/clicked\" hx-swap=\"outerHTML\" hx-headers='{\"X-CSRF-Token\": \"" csrf-token "\"}'>
  Click Me
</button>
</html>")))

两种方式都能让htmx发起POST请求时自动带上CSRF令牌,服务器验证通过后就不会返回403错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:25:13