Redirect 重定向回原始页面

Redirect 重定向回原始页面,redirect,clojure,compojure,Redirect,Clojure,Compojure,给定一些compojure路线: (defroutes app-routes (GET "/" [] (display-some-html)) (GET "/story" [] (display-more-html)) (GET "/classes" [] (display-other-html)) (POST "/delete" [id] (do (delete-some-id-from-db id) (magic-redi

给定一些compojure路线:

(defroutes app-routes
  (GET "/" [] (display-some-html))
  (GET "/story" [] (display-more-html))
  (GET "/classes" [] (display-other-html))
  (POST "/delete" [id] (do (delete-some-id-from-db id)
                           (magic-redirect-function)))
  (route/resources "/")
  (route/not-found "Not Found"))

假设我能够从
/
/story
/classes
发布到
/delete
。如何重定向到POST请求所源自的页面?

通常的方法是在会话中使用上一个url,并在操作后将用户重定向到该页面/呈现相应的视图。如果您正在使用,则已包含wrap会话

您可以从中执行类似于此示例的操作,只需将其更改为存储请求路径而不是计数

(defn handler [{session :session}]
  (let [count   (:count session 0)
        session (assoc session :count (inc count))]
    (-> (response (str "You accessed this page " count " times."))
        (assoc :session session))))

我的解决方案基于迭戈的建议,使用
lib noir

(ns my-project.handler
    (:require (compojure [handler :as handler]
                         [route :as route]
                         [core :refer :all])
              [ring.util.response :refer [redirect]]
              [noir.util.middleware :as middleware]
              [noir.session :as session]))

(defroutes app-routes
  (GET "/" [] 
       (session/put! :origin "/")
       (display-some-html))
  (GET "/story" [] 
       (session/put! :origin "/story")
       (display-more-html))
  (GET "/classes" [] 
       (session/put! :origin "/classes")
       (display-other-html))
  (POST "/delete" [id] 
        (delete-some-id-from-db id)
        (redirect (session/get! :origin "/"))) ; "/" is an optional default
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (-> 
   (handler/site app-routes)
    session/wrap-noir-session))

它可以工作,但我不认为它很优雅。

使用referer头重定向回

(let [back (get (:headers request) "referer")]
  (redirect-to back))

死鬼的建议是最好的。在这里,您可以找到我的解决方案,使用libnoir库自动重定向到主页。我希望这对某人有帮助

    (ns hue-web-app.core
    (:require   [ring.middleware.defaults :refer [wrap-defaults api-        defaults site-defaults]]
                [ring.util.response :as response]        ;;from ring
                [compojure.core :refer :all]
                [compojure.route :as route]            
                [noir.util.middleware :as middleware]
                [noir.session :as session]]  ;;noir for redirect to work

    (defroutes hue-app-routes
      (GET "/" [] (session/put! :origin "/")
                  (io/file "resources/testsite.html"))
      (GET "/turn-off" [] (turn-group-off 3 user) 
                          (response/redirect (session/get! :origin "/")))
      (GET "/turn-on" [] (turn-group-on 3 user)
                         (response/redirect (session/get! :origin "/"))))

    ;;STARTING THE SERVER
    ;;--------------------------------------------------------------        ------------
    (defn siteparams
      []
      (run-jetty (-> #'hue-app-routes
                     wrap-reload
                     wrap-restful-format
                     wrap-params
                     session/wrap-noir-session
                     )
                 {:port 5003
                  :join? false}))

这个答案很好,但也许它还应该包括所需重定向功能的详细信息?如果您计划在许多路由中重用会话/放置部分,您可以编写一个中间件来封装它。对于代码重复来说,三个就可以了。此外,您还可以将do中的所有表达式放在单独的行中。这将使它们正确缩进,而不会产生不必要的代码。每次使用POST进行删除操作时,都会有一只小猫死亡。您还可以在POST请求中包含要重定向到的URL(即当前页面的URL),然后在调用
ring.util.response/redirect
时将其用作死鬼答案演示。@schaueho POST在我的实际代码中更改为删除。在请求中包含重定向url也是一个很好的解决方案,尽管目前session+中间件解决方案看起来最干净。session的一个潜在问题是,假设请求是按顺序来的。如果它们同时出现,比如说用户在同一个浏览器中打开了几个选项卡,那么用户可以被重定向到一个意外的页面。在delete请求中包含resirect url的解决方案没有那个特殊的问题。