代码之家  ›  专栏  ›  技术社区  ›  user275667

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

  •  4
  • user275667  · 技术社区  · 7 年前

    使用创建项目 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))
    

    因此,我面临的问题是,我不知道如何从控制器文件中获取或设置cookie。我尝试过的事情:

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

    任何帮助都将不胜感激。关于这方面的文档不多,因此很遗憾,这个问题花费了相当多的时间。

    3 回复  |  直到 7 年前
        1
  •  7
  •   user275667    7 年前

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

    • 当你听到会话时,会话不是你所想的。这只是一个签名的cookie,而且文档记录得很差。别理它。我发现的少数教程经常出现错误,使用“sessions”来表示“signed cookie”。文档甚至可以互换使用cookie和会话。为什么?我不知道,因为它们是完全独立的数据存储方法。会话是服务器端内存存储,Cookie是客户端浏览器存储。

    • :需要标头,否则cookie将下载到空文本文件中。花了很长时间才弄明白为什么会这样。

    • :路径必须进入cookie正文,否则cookie将仅在设置cookie的页面中保留。你可能会想:路径应该在饼干之后,在身体之上。对于我来说,没有任何意义:路径为什么会与值一起包含在hashmap中。同样,也没有文档说明这是如何或为什么花了很长时间。

    现在了解如何执行此操作:

    在这里,您可以从处理程序内部将cookie传递给控制器。如果您使用“lein new compojure app name”创建应用程序,则默认情况下Cookie可用。我必须阅读源代码才能弄明白这一点。

    默认命名空间(应用程序名称/处理程序.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))
    

    你的应用程序路由(应用程序名称/处理程序.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"})
    

    处理程序的底部。clj对指定的路由使用默认包装(app name/handler.clj)

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

    这是一个非常简单的问题,但事实证明要复杂得多。我花了三天的时间才把上面的一切都弄清楚。我刚接触Clojure/Ring/Compojure,但这是我编程以来最糟糕的经历。

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

    不管怎样,我希望这对某人有所帮助。

        2
  •  1
  •   Michel A.    5 年前

    我个人花了相当长的时间阅读饼干,因为我对 destructuring in compojure

    在使用wrap cookies处理程序包装应用程序之后,需要对cookies变量“clojure-way”而不是“compojure-way”进行解构,因为cookies映射不在请求参数映射中。

    不起作用的示例:

      (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)]))))
    

    希望这有帮助,

        3
  •  0
  •   Ahmed    7 年前

    使用环包装cookie这将在您的请求映射中添加cookie密钥,更多详细信息在这里,然后使用compjure您可以访问请求映射,并且可以使用它。

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