使用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
相关产品推荐
相关产品推荐

