我有一个名为index.html
的静态文件,当有人请求/
时,我想要它被提供。通常情况下,Web服务器会默认这样做,但是Compojure不会。我该如何让Compojure在有人请求/
时提供index.html
呢?
这是我用于静态目录的代码:
; match anything in the static dir at resources/public
(route/resources "/")
另一种方法是在其他路由中创建一个重定向或直接响应。如下所示:
(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"))
"/"路由返回public文件夹中存在的"index.html"文件响应。"/a"路由通过直接'内联'文件index.html来响应。
有关ring响应的更多信息:https://github.com/mmcgrana/ring/wiki/Creating-responses
编辑:删除不必要的[ring.adapter.jetty]
导入。
(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)一样简单。没有必要过于复杂。
这将是一个非常简单的 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)))
这个很好用,不需要编写环中间件。
(:require [clojure.java.io :as io])
(defroutes app-routes
(GET "/" [] (io/resource "public/index.html")))
在查看了这里很多答案之后,我正在使用以下代码:
(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"))))
请查看ring-defaults。它有您应该在项目中使用的最佳实践中间件。
resp/content-type
应该被包装在一个表单中吗? - Petrus Theron最近我发现当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)))))
(GET "/about/" [] (ring.util.response/content-type
(ring.util.response/resource-response "about/index.html" {:root "public"}) "text/html"))
(GET "/*" [] r/static)
(GET "/" [] (clojure.java.io/resource "public/index.html"))
虽然这个可以工作
(GET "/" [] (clojure.java.io/resource "public/index.html"))
(GET "/*" [] r/static)
显然,*
也匹配空字符串,但我认为顺序根本不重要。
wrap-content-type
可能会破坏你的代码。我发布了一个答案来解决这个问题。 - fasfsfgs