web-dev-qa-db-ja.com

Compojureのデフォルトで/でindex.htmlを提供します

誰かがindex.htmlを要求したときに提供したい/という静的ファイルがあります。通常、Webサーバー デフォルトでこれを行います ですが、Compojureはそうではありません。誰かがindex.htmlを要求したときに、Compojureを/に提供するにはどうすればよいですか?

静的ディレクトリに使用しているコードは次のとおりです。

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

これは非常に単純なリングミドルウェアになります。

(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)))
21
amalloy

別の方法として、追加のルートでリダイレクトまたは直接応答を作成することもできます。そのようです:

(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]インポートを削除しました。

39
Paul
(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)と同じくらい簡単です。物事を過度に複雑にする必要はありません。

26
jandrewthompson

これは問題なく機能します。リングミドルウェアを書く必要はありません。

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

(defroutes app-routes 
(GET "/" [] (io/resource "public/index.html")))
19
Binita Bharati

ここで多くの回答を見た後、私は次のコードを使用しています。

(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)に残ります。
  • それは他のミドルウェアで動作します(いくつかのリングデフォルトミドルウェアで使用すると多くの答えが壊れます)。
  • Content-typeを提供するため、wrap-content-typeミドルウェアで動作します。

ring-defaults を確認してください。プロジェクトで使用する必要のあるミドルウェアのベストプラクティスがあります。

9
fasfsfgs

最近、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

UPDATED:例を動作するバージョンに置き換えました。

3
tvaughan

他のコードが機能しない場合は、このコードを試してください。

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

ビニータ、私が経験している落とし穴を考えてみてください。 Compojureルートを定義する順序の重要性に関するドキュメントが見つかりませんでしたが、これが機能しないことがわかりました

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

これは機能しますが

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

明らかに*は空の文字列にも一致しますが、順序はまったく問題ではないと思いました。

0
Jaime Agudo