34

我有一个名为的静态文件index.html,我想在有人请求时提供/. 通常 web 服务器默认会这样做,但 Compojure 不会。index.html当有人请求时,我如何让 Compojure 服务/

这是我用于静态目录的代码:

; match anything in the static dir at resources/public
(route/resources "/")
4

8 回答 8

41

另一种方法是在附加路由中创建重定向或直接响应。像这样:

(ns compj-test.core
  (:use [compojure.core])
  (:require [compojure.route :as route]
            [ring.util.response :as resp]))

(defroutes main-routes
  (GET "/" [] (resp/file-response "index.html" {:root "public"}))
  (GET "/a" [] (resp/resource-response "index.html" {:root "public"}))
  (route/resources "/")
  (route/not-found "Page not found"))

“/”路由返回“index.html”的文件响应,该文件存在于公用文件夹中。“/a” 路由通过“内联”文件 index.html 直接响应。

有关环响应的更多信息:https ://github.com/mmcgrana/ring/wiki/Creating-responses

编辑:删除了不必要[ring.adapter.jetty]的导入。

于 2011-10-11T18:45:18.933 回答
28
(ns compj-test.core
  (:use [compojure.core])
  (:require
        [ring.util.response :as resp]))

(defroutes main-routes
  (GET "/" [] (resp/redirect "/index.html")))

您要求的是从 / 到 /index.html 的重定向。它就像(resp/redirect target)一样简单。没有必要把事情复杂化。

于 2013-04-11T13:47:07.990 回答
24

这将是一个非常简单的 Ring 中间件:

(defn wrap-dir-index [handler]
  (fn [req]
    (handler
     (update-in req [:uri]
                #(if (= "/" %) "/index.html" %)))))

只需使用此函数包装您的路线,并在其余代码看到它们之前将/请求转换为请求。/index.html

(def app (-> (routes (your-dynamic-routes)
                     (resources "/"))
             (...other wrappers...)
             (wrap-dir-index)))
于 2011-10-11T18:09:29.167 回答
19

这工作得很好。无需编写环中间件。

(:require [clojure.java.io :as io])

(defroutes app-routes 
(GET "/" [] (io/resource "public/index.html")))
于 2013-10-05T05:34:48.097 回答
13

在这里查看了很多答案后,我正在使用以下代码:

(ns app.routes
  (:require [compojure.core :refer [defroutes GET]]
            [ring.util.response :as resp]))

(defroutes appRoutes
  ;; ...
  ;; your routes
  ;; ...
  (GET "/" []
       (resp/content-type (resp/resource-response "index.html" {:root "public"}) "text/html"))))
  • 没有重定向;
  • 不需要其他中间件;
  • index.html 保留在正确的文件夹中(resources/public/index.html);
  • 它可与其他中间件一起使用(与某些环默认中间件一起使用时,很多答案都会中断);
  • 它提供内容类型,因此它可以与 wrap-content-type 中间件一起使用。

检查环默认值。它具有您应该在项目中使用的最佳实践中间件。

于 2015-09-10T01:29:02.417 回答
3

最近我发现当 Clojure/Compojure 应用程序作为 .war 在 Jetty 或 Tomcat 下运行时,@amalloy 的答案不起作用。在这种情况下:path-info需要更新。另外,我认为这个版本可以处理任何路由,而不仅仅是“根”路由。

(defn- wrap-dir-index [handler]
  (fn [request]
    (handler
     (let [k (if (contains? request :path-info) :path-info :uri) v (get request k)]
       (if (re-find #"/$" v)
         (assoc request k (format "%sindex.html" v))
         request)))))

另请参阅:https ://groups.google.com/forum/#!msg/compojure/yzvpQVeQS3w/RNFkFJaAaYIJ

更新:将示例替换为有效的版本。

于 2012-12-23T21:06:49.117 回答
1

当其他代码不起作用时,请尝试此代码。

(GET "/about/" [] (ring.util.response/content-type
                     (ring.util.response/resource-response "about/index.html" {:root "public"}) "text/html"))
于 2015-06-25T05:51:47.730 回答
0

只是一个考虑 Binita,我一直在经历的一个陷阱。尽管我找不到任何有关订单定义 Compojure 路由的重要性的文档,但我发现这不起作用

(GET "/*" [] r/static) 
(GET "/" [] (clojure.java.io/resource "public/index.html"))

虽然这确实有效

(GET "/" [] (clojure.java.io/resource "public/index.html"))
(GET "/*" [] r/static) 

显然, *匹配也匹配空字符串,但我认为顺序根本不重要。

于 2014-03-04T00:01:17.767 回答