如何使用compojure设置和获取cookie?

时间:2018-03-27 00:16:15

标签: cookies clojure compojure

使用lein new compojure project-name创建项目,并让服务器引用(wrap-defaults project-name site-defaults)

在我的处理程序中,我正在调用控制器并将params传递给那些控制器。项目结构:

handler.clj ;; ring accesses def app
controllers/app.clj ;; where route params are sent
example: (GET "/signup" {params :params} (controller-app/signup params))

所以我遇到的问题是我无法弄清楚如何从控制器文件中获取或设置cookie。我尝试过的事情:

  • 将cookie作为参数传递:{cookies:cookies}。我能够查看默认cookie但无法设置任何数据。
  • 使用cookie响应和cookie请求。同样的问题是无法添加到cookie中。
  • 在每条路线中使用:cookie并且什么也得不回来。

非常感谢任何帮助。没有太多关于此的文档,所以遗憾的是问题需要相当长的时间。

3 个答案:

答案 0 :(得分:3)

终于能够用蛮力来解决它。当人们说Clojure的文档相当稀疏时,这不是开玩笑。关于戒指的几点说明:

  • 当您听到会话时,会话不是您的想法。它只是一个签名的cookie和一个记录不佳的cookie。只是忽略它。我发现的一些教程经常发现错误,当他们的意思是“签名的cookie”时使用了“会话”。文档甚至可以互换使用cookie和会话。为什么?我不知道它们是完全独立的存储数据的方法。会话是内存存储中的服务器端,cookie是客户端浏览器存储。

  • :需要标头,否则cookie只会下载到空文本文件中。永远了解为什么会这样。

  • :路径必须进入cookie主体,否则cookie将仅存在于设置cookie的页面。你会想:路径会追求:饼干和上面:身体。对我来说,为什么路径将与值一起包含在hashmap中是没有意义的。同样,没有关于如何或为什么这样做的文档也是如此。

现在讨论如何做到这一点:

在这里,您可以从处理程序内部将cookie传递给控制器​​。如果您使用“lein new compojure app-name”来创建应用程序,则默认情况下可以使用Cookie。我必须阅读源代码来解决这个问题。

默认命名空间(app-name / handler.clj) -

(ns some-namespace.handler
  [compojure.core :refer :all]
  [compojure.route :as route]
  [ring.middleware.defaults :refer [wrap-defaults site-defaults]
  [app-name.controllers.home :as home-controller))

您的应用路线(app-name / handler.clj) -

(defroutes app-routes
  (GET "/" {cookies :cookie} (home-controller/home cookies)))

以下是设置cookie本身的方法(app-name / controllers / home.clj)。

(ns app-name.controllers.home)

(defn home [cookies]
  {:headers {"Content-Type" "Set-Cookie"},
   :cookies {"cookie-name" {:value "cookie-value", :path "/"}},
   :body "setting a cookie"})

handler.clj的底部使用指定路由的默认包装(app-name / handler.clj)

(def app
  (wrap-defaults app-routes site-defaults ))

这是一个非常简单的问题,结果证明要复杂得多。我花了3天的时间才弄清楚以上所有情况。我是Clojure / Ring / Compojure的新手,但这是我编程中最糟糕的经历。

这真的是一个足够抽象变得危险的问题(基本上没有什么是显而易见的)。如果需要更广泛的采用,像Ring这样的图书馆需要更好地记录并解释。

无论如何,我希望这有助于某人。

答案 1 :(得分:1)

由于对destructuring in compojure的理解不足,我个人花了相当长的时间使cookie读取。

在使用wrap-cookies处理程序包装应用程序之后,由于Cookie映射不在请求参数映射中,因此需要解构cookie变量“ clojure方法”而不是“ compojure方法”。

无效的示例:

  (GET "/read-cookie" [cookies]
   (let [name (get-in cookies ["name" :value] "")]
     (if (empty? name)
       (layout/common [:h1 "I don't read a cookie"])
       (layout/common [:h1 (str "I read a cookie : " name)]))))

有效的示例:

  (GET "/read-cookie" {:keys [cookies]} ;; or {cookies :cookies}
   (let [name (get-in cookies ["name" :value] "")]
     (if (empty? name)
       (layout/common [:h1 "I don't read a cookie"])
       (layout/common [:h1 (str "I read a cookie : " name)]))))

希望这会有所帮助,

答案 2 :(得分:0)

使用来自环的wrap-cookie,这将在您的请求地图中添加cookie密钥,更多详细信息在此处,然后使用compjure您可以访问req地图,并且您可以使用它。

https://github.com/ring-clojure/ring/wiki/Cookies