Подавать index.html в/по умолчанию в Compojure
У меня есть статический файл с именем index.html
, который я хотел бы обслуживать, когда кто-то запрашивает /
. Обычно веб-серверы делают это по умолчанию, но Compojure этого не делает. Как я могу сделать Compojure подавать index.html
, когда кто-то запрашивает /
?
Вот код, который я использую для статического каталога:
; match anything in the static dir at resources/public
(route/resources "/")
Ответы
Ответ 1
Это было бы довольно простое промежуточное ПО 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)))
Ответ 2
Альтернативой может быть создание либо перенаправления, либо прямого ответа на дополнительном маршруте. Например:
(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" напрямую отвечает на "inlineing" файл index.html.
Подробнее о кольцевых ответах: https://github.com/mmcgrana/ring/wiki/Creating-responses
EDIT: удалить ненужный [ring.adapter.jetty]
импорт.
Ответ 3
(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). Не нужно больше усложнять вещи.
Ответ 4
Это работает отлично. Не нужно писать кольцо среднего уровня.
(:require [clojure.java.io :as io])
(defroutes app-routes
(GET "/" [] (io/resource "public/index.html")))
Ответ 5
После просмотра большого количества ответов здесь я использую следующий код:
(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. Он имеет передовые методы, которые вы должны использовать в своих проектах.
Ответ 6
Недавно я обнаружил, что ответ @amalloy не работает, когда приложение Clojure/Compojure запущено под Jetty или Tomcat в качестве .war. В этом случае :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
ОБНОВЛЕНО: Замененный пример с версией, которая работает.
Ответ 7
когда другой код не работает,
попробуйте этот код.
(GET "/about/" [] (ring.util.response/content-type
(ring.util.response/resource-response "about/index.html" {:root "public"}) "text/html"))
Ответ 8
Просто внимание Бинита, которое я испытал. Несмотря на то, что я не смог найти документацию о важности заказа, определяющего маршруты Compojure, я узнал, что это не работает.
(GET "/*" [] r/static)
(GET "/" [] (clojure.java.io/resource "public/index.html"))
хотя это работает
(GET "/" [] (clojure.java.io/resource "public/index.html"))
(GET "/*" [] r/static)
Очевидно, что *
соответствует также пустой строкой, но я думал, что порядок вообще не имеет значения.