使用Clojure戒指服务静态资源

时间:2019-08-06 01:33:56

标签: clojure compojure ring

我正在学习如何使用Clojure的Ring创建Web应用程序。我正在尝试提供一个静态的 .html 文件,该文件通过其头部的<link>标记包含对.css文件的引用。 .css文件与我要提供服务的index.html文件位于同一目录中,但是,.css文件未加载(我收到500状态代码错误,原因短语为:

  

响应图为零

这是我的下面的代码:

(defroutes approutes
  (GET "/" reqmap
    (resource-response "index.html")))


(def server (run-jetty #'approutes {:join? false, :port 3000}))

我在这里想念什么?以及如何提供引用了其他文件(.css,.js,.jpeg等)的html文件?我在wrap-resource命名空间中使用Ring的ring.middleware.resource中间件很幸运(尽管我无法完全解释为什么),尽管该功能仅在请求映射与静态资源匹配时才使用(并且如您所见,路由“ /”本身不匹配资源。

谢谢。

1 个答案:

答案 0 :(得分:3)

您需要添加一点中间件,该中间件将负责从您可以选择的文件夹中提供静态文件,如下所示:

;; Add to your (ns :requires at the top of the file)
(:require [ring.middleware.resource :refer wrap-resource])

;; more of your existing code here...

(def app
  (wrap-resource approutes "public")) ;; serve static files from "resources/public" in your project

(def server (run-jetty #'app {:join? false, :port 3000}))

这足以使您开始工作,因此,如果您启动服务器,则应该能够在诸如http://localhost:3000/style.css之类的地址中打开文件,该地址应在项目的public/resources/style.css中找到。任何其他静态文件都可以使用。 Ring wiki in Github中有一个指南,介绍了可以使用的两个类似功能(中间件)。

接下来,在您的index.html文件中,您应该可以引用其他文件,例如CSS文件,如下所示:

<html>
  <head>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <!-- and son on... -->

这是我前一段时间写的一个示例项目,确实显示了相同的想法:https://github.com/dfuenzalida/antizer-demo


UPDATE

我已经从头开始进行了快速运行,这应该可以帮助您找到问题所在。

使用以下项目创建了一个新项目:

lein new app hello-ring

实际上,这个名称有点误导,因为我们将同时使用Ring和Compojure。

我们将使用以下内容更新文件project.clj

(defproject hello-ring "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [compojure "1.6.1"]
                 [ring/ring-core "1.6.3"]
                 [ring/ring-jetty-adapter "1.6.3"]]
  :main ^:skip-aot hello-ring.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

现在让我们编辑文件src/hello_ring/core.clj,其内容应如下所示:

(ns hello-ring.core
  (:require [ring.adapter.jetty :refer [run-jetty]]
            [ring.middleware.resource :refer [wrap-resource]]
            [ring.util.response :refer [resource-response]]
            [compojure.core :refer [defroutes GET]])
  (:gen-class))

(defroutes approutes
  (GET "/" []
       (resource-response "public/index.html")))

(def app
  (-> approutes
      (wrap-resource "public"))) ;; files from resources/public are served

(defn server []
  (run-jetty app {:join? false, :port 3000}))

(defn -main [& args]
  (server))

最后,让我们创建几个静态资源。创建文件夹结构resources/public/css,并在文件resources/public/css/style.css中输入以下内容:

body {
    font-face: sans-serif;
    padding-left: 20px;
}

...以及resources/public/index.html中的基本HTML文件,其中包含以下内容:

<html>
  <head>
    <title>It works!</title>
    <link rel="stylesheet" href="css/style.css" />
  </head>
  <body>
    <h1>it works!</h1>
  </body>
</html>

...就是这样。 HTML文件将尝试加载CSS文件。保存所有内容,并检查其是否与以下文件夹结构匹配:

.
├── CHANGELOG.md
├── doc
│   └── intro.md
├── LICENSE
├── project.clj
├── README.md
├── resources
│   └── public
│       ├── css
│       │   └── style.css
│       └── index.html
├── src
│   └── hello_ring
│       └── core.clj
└── test
    └── hello_ring
        └── core_test.clj

现在,您应该可以使用以下命令从命令行启动服务了:

lein run

输出将如下所示:

$ lein run
2019-08-05 23:46:14.919:INFO::main: Logging initialized @1221ms
2019-08-05 23:46:16.281:INFO:oejs.Server:main: jetty-9.2.21.v20170120
2019-08-05 23:46:16.303:INFO:oejs.ServerConnector:main: Started ServerConnector@2c846d55{HTTP/1.1}{0.0.0.0:3000}
2019-08-05 23:46:16.303:INFO:oejs.Server:main: Started @2606ms

http://0.0.0.0:3000/中连接到服务器...您应该在浏览器中看到带有它能正常工作!消息和基本的CSS重置的页面。在控制台中,您最有可能看到一些异常,因为浏览器尝试从服务器中加载文件/favicon.ico,该文件不存在(您现在可以将其创建为空文件)。

我希望这会有所帮助。

相关问题