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

use*_*667 4 cookies clojure compojure

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

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

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

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

  • 将 cookie 作为参数传递:{cookies :cookies}。我能够查看默认 cookie,但无法设置任何数据。
  • 使用 cookie-response 和 cookie-request。无法添加到 cookie 的相同问题。
  • 在每条可能的路线中使用 :cookie 并且一无所获。

任何帮助将非常感激。没有太多关于此的文档,因此不幸的是,该问题花费了相当长的时间。

use*_*667 7

终于可以用蛮力解决了。当人们说 Clojure 的文档非常稀少时,这不是开玩笑。关于戒指的一些注意事项:

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

  • :headers 是必需的,否则 cookie 只会下载到一个空的文本文件中。花了很长时间才弄清楚为什么会这样。

  • :path 必须进入 cookie 主体,否则 cookie 只会在设置了 cookie 的页面上持续存在。你会认为 :path 会在 :cookies 和 :body 之后。为什么 :path 将与值一起包含在哈希图中对我来说毫无意义。同样,没有关于如何或为什么的文档,所以这也花了很长时间。

现在来看看如何做到这一点:

在这里,您将 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))
Run Code Online (Sandbox Code Playgroud)

您的应用程序路由 (app-name/handler.clj) -

(defroutes app-routes
  (GET "/" {cookies :cookie} (home-controller/home cookies)))
Run Code Online (Sandbox Code Playgroud)

以下是设置 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"})
Run Code Online (Sandbox Code Playgroud)

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

(def app
  (wrap-defaults app-routes site-defaults ))
Run Code Online (Sandbox Code Playgroud)

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

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

无论如何,我希望这对某人有所帮助。