【问题标题】:Serve index.html at / by default in Compojure在 Compojure 中默认在 / 处提供 index.html
【发布时间】:2011-12-05 11:45:11
【问题描述】:

我有一个名为index.html 的静态文件,我想在有人请求/ 时提供该文件。通常是网络服务器do this by default,但 Compojure 没有。当有人请求 / 时,如何让 Compojure 服务 index.html

这是我用于静态目录的代码:

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

【问题讨论】:

    标签: clojure compojure


    【解决方案1】:

    在这里查看了很多答案后,我正在使用以下代码:

    (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。它具有您应该在项目中使用的最佳实践中间件。

    【讨论】:

    • 获取表单缺少空参数[],否则这正是我需要的,谢谢!
    • @hequ 谢谢!用缺少的括号更新了答案。
    • 不应该将resp/content-type 包裹在表单中吗?
    【解决方案2】:

    当其他代码不起作用时, 试试这个代码。

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

    【讨论】:

    • 请为您的答案添加一些解释,以使其对其他读者更有用。
    • 很好的答案。它使用环提供的解决方案提供指定其内容类型的资源。
    【解决方案3】:

    只是一个考虑 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 可能会破坏您的代码。我发布了an answer 来解决这个问题。
    【解决方案4】:

    这很好用。无需编写环中间件。

    (:require [clojure.java.io :as io])
    
    (defroutes app-routes 
    (GET "/" [] (io/resource "public/index.html")))
    

    【讨论】:

    • 不知道它是否回答了这个问题,但它帮助我满足了我的需要!点赞!谢谢!
    • 小心不要提供您想要的内容类型。另一个中间件,例如 wrap-content-type 可能会破坏您的代码。我发布了an answer 来解决这个问题。
    【解决方案5】:
    (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) 一样简单。不需要把事情搞得太复杂。

    【讨论】:

    • 这是最直接、最合乎逻辑的回应,谢谢!
    【解决方案6】:

    最近我发现当 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

    更新:将示例替换为有效的版本。

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

      • 嗨。 (GET "/" [] (resp/resource-response "index.html" {:root "public"})) 非常适合我。
      • 小心不要提供您想要的内容类型。另一个中间件,例如 wrap-content-type 可能会破坏您的代码。我发布了an answer 来解决这个问题。
      【解决方案8】:

      这将是一个非常简单的 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)))
      

      【讨论】:

      • 我想我的意思是:Compojure 不会这样做,因为使用 Ring 很容易做到这一点。您的 Clojure Web 堆栈不是一个包罗万象的平台,而是一系列可插入的专用工具。使用专为其设计的工具解决问题 X。
      猜你喜欢
      • 2016-06-20
      • 2014-10-10
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多