如何在Clojure Web应用中访问表单的单个字段?
解决表单字段访问问题的方案
看起来你是刚上手Clojure的Compojure+Hiccup开发,碰到了POST表单后没法提取单个字段的问题对吧?我来帮你一步步解决:
问题根源
你现在的display-city函数直接把整个request对象转成字符串输出了,但表单提交的字段值其实存在request的:params键下面——不过前提是你得先配置好参数解析的中间件,不然Compojure没法帮你解析POST的表单数据。
步骤1:添加必要的中间件
首先,你的应用需要用上参数解析的中间件,不然拿不到表单参数。最简单的方式是用handler/site包装你的路由,它会自动包含wrap-params、wrap-form-params这些常用中间件:
(require '[compojure.handler :as handler]) (def app (-> (defroutes main-routes (GET "/" [] homepage) (POST "/city" request display-city) (route/resources "/") (route/not-found "Not Found")) (handler/site)))
如果你想更精细控制,也可以单独添加中间件:
(require '[ring.middleware.params :refer [wrap-params]]) (def app (-> (defroutes main-routes (GET "/" [] homepage) (POST "/city" request display-city) (route/resources "/") (route/not-found "Not Found")) wrap-params))
步骤2:修改函数提取单个字段
假设你的Hiccup表单里有个name为city的输入框(比如[:input {:type "text" :name "city"}]),那你可以从request的:params里取出这个值:
(defn display-city [request] (let [city (get-in request [:params "city"])] ; 参数名要和表单的name属性完全一致 (html5 [:div {:class "the-city"} [:h2 "ALL ABOUT YOUR CITY"] [:ul [:li "Your city is " (str city) "! That's all"]]])))
更简洁的写法:路由参数绑定
Compojure还支持直接在路由里绑定表单参数,不用手动从request里取,代码会更清爽:
(defroutes main-routes (GET "/" [] homepage) (POST "/city" [city] ; 这里的city就是表单里name="city"的字段值 (html5 [:div {:class "the-city"} [:h2 "ALL ABOUT YOUR CITY"] [:ul [:li "Your city is " (str city) "! That's all"]]])) (route/resources "/") (route/not-found "Not Found"))
最后检查你的表单
一定要确保表单里的输入框有正确的name属性,比如:
[:form {:action "/city" :method "post"} [:label "Your City:"] [:input {:type "text" :name "city" :placeholder "Enter city name"}] [:button {:type "submit"} "Submit"]]
没有name属性的话,浏览器不会把这个字段的数据提交给服务器,自然就拿不到值啦。
内容的提问来源于stack exchange,提问作者orangeorangepeel
相关产品推荐
相关产品推荐

