2011-10-11 51 views
27

我有一个名为index.html的静态文件,我想在有人请求/时提供。通常web服务器do this by default,但Compojure没有。当有人要求/时,如何让Compojure服务index.html在Compojure中默认使用index.html

下面是我使用的静态目录代码:

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

回答

20

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

(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))) 
+3

我想我的观点是:Compojure没有这样做,因为用Ring来代替它很容易。您的Clojure Web堆栈不是一个全面的平台,而是一系列可插拔和专用的工具。用专为它设计的工具解决问题X. – amalloy

38

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

(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]导入。

+5

嗨。 (GET“/”[](resp/resource-response“index.html”{:root“public”}))对我来说非常合适。 – joshua

+0

小心不要提供您想要的内容类型。另一个中间件如'wrap-content-type'可能会破坏你的代码。我发布了[答案](http://stackoverflow.com/a/32491623/1707589)解决这个问题。 – fasfsfgs

3

最近我发现,当Clojure/Compojure应用程序在Jetty或Tomcat下作为.war运行时,@ 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

更新:替换,例如与工作的版本。

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

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

你要求的是从/到/index.html的重定向。其简单如(resp /重定向目标)。无需过度复杂的事情。

+2

这是最直接和最合理的回应,谢谢! – scape

+1

是的,这是唯一一个为我工作的人 – Zubair

18

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

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

(defroutes app-routes 
(GET "/" [] (io/resource "public/index.html"))) 
+0

不知道它是否回答了这个问题,但它帮助我获得了我需要的东西! Upvoted!谢谢! – leontalbot

+0

小心不要提供您想要的内容类型。另一个中间件如'wrap-content-type'可能会破坏你的代码。我发布了[答案](http://stackoverflow.com/a/32491623/1707589)解决这个问题。 – fasfsfgs

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) 

显然*配衬也为空字符串的重要性,任何文件但我认为这个命令根本不重要。

+0

小心不要提供你想要的内容类型。另一个中间件如'wrap-content-type'可能会破坏你的代码。我发布了[答案](http://stackoverflow.com/a/32491623/1707589)解决这个问题。 – fasfsfgs

1

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

(GET "/about/" [] (ring.util.response/content-type 
        (ring.util.response/resource-response "about/index.html" {:root "public"}) "text/html")) 
+2

请为您的答案添加一些解释,以使其对其他读者更有用。 –

+0

很好的答案。它使用环提供的解决方案提供指定其内容类型的资源。 – fasfsfgs

7

在这里观看了很多的答案后,我用下面的代码:

(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中间件一起使用。

检查ring-defaults。它具有您应该在您的项目中使用的最佳实践中间件。

+0

获取表单缺少空参数[],否则这正是我所需要的,谢谢! – hequ

+0

@hequ谢谢!用缺少的括号更新答案。 – fasfsfgs

+0

不应该'resp/content-type'被包装在一个表单中? –

相关问题