我有一個名爲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 "/")
我有一個名爲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 "/")
這將是一個非常簡單的環中間件:
(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)))
另一種方法是在附加路由中創建重定向或直接響應。像這樣:
(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]
導入。
最近我發現,當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
更新:替換,例如與工作的版本。
這工作得很好。無需編寫一個環形中間件。
(:require [clojure.java.io :as io])
(defroutes app-routes
(GET "/" [] (io/resource "public/index.html")))
不知道它是否回答了這個問題,但它幫助我獲得了我需要的東西! Upvoted!謝謝! – leontalbot
小心不要提供您想要的內容類型。另一箇中間件如'wrap-content-type'可能會破壞你的代碼。我發佈了[答案](http://stackoverflow.com/a/32491623/1707589)解決這個問題。 – fasfsfgs
只是一個考慮Binita,一直困擾我一直在經歷。儘管我無法找到有關訂單定義的Compojure路線我發現這行不通
(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'可能會破壞你的代碼。我發佈了[答案](http://stackoverflow.com/a/32491623/1707589)解決這個問題。 – fasfsfgs
當其他代碼不起作用時, 請嘗試此代碼。
(GET "/about/" [] (ring.util.response/content-type
(ring.util.response/resource-response "about/index.html" {:root "public"}) "text/html"))
請爲您的答案添加一些解釋,以使其對其他讀者更有用。 –
很好的答案。它使用環提供的解決方案提供指定其內容類型的資源。 – fasfsfgs
在這裏觀看了很多的答案後,我用下面的代碼:
(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。它具有您應該在您的項目中使用的最佳實踐中間件。
我想我的觀點是:Compojure沒有這樣做,因爲用Ring來代替它很容易。您的Clojure Web堆棧不是一個全面的平臺,而是一系列可插拔和專用的工具。用專爲它設計的工具解決問題X. – amalloy