使用 Clojure 的 Ring 提供静态资源
Serve static resources using Clojure's Ring
我正在学习如何使用 Clojure 的 Ring 创建 Web 应用程序。我正在尝试提供静态 .html 文件,该文件通过其头部的 <link>
标记包含对 .css 文件的引用. .css 文件与我尝试提供的 index.html 文件位于同一目录中,但是,未加载 .css 文件(我收到 500 错误带有原因短语的状态代码:
Reponse map is nil
下面是我的代码:
(defroutes approutes
(GET "/" reqmap
(resource-response "index.html")))
(def server (run-jetty #'approutes {:join? false, :port 3000}))
我在这里错过了什么?以及如何提供引用了其他文件(.css、.js、.jpeg 等)的 html 文件?我有一些运气(虽然我不能完全解释为什么)在 ring.middleware.resource
命名空间中使用 Ring 的 wrap-resource
中间件,尽管该函数仅在请求映射匹配静态资源时使用(并且如您所见,路由“/”与资源本身不匹配。
谢谢。
您需要添加一点中间件,它将负责从您可以select的文件夹中提供静态文件,如下所示:
;; 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 which should be found in public/resources/style.css
in your project. Any other static files should work. There's a guide in the 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
更新
我从头开始快速 运行,这应该可以帮助您找到问题所在。
创建了一个新项目:
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/ 中连接到服务器...您应该会在浏览器中看到您的页面,其中包含 It works! 消息和基本的 CSS重启。在控制台中,您很可能会看到一些异常,因为浏览器试图从您的服务器加载文件 /favicon.ico
,该文件不存在(您现在可以将其创建为空文件)。
希望对您有所帮助。
我正在学习如何使用 Clojure 的 Ring 创建 Web 应用程序。我正在尝试提供静态 .html 文件,该文件通过其头部的 <link>
标记包含对 .css 文件的引用. .css 文件与我尝试提供的 index.html 文件位于同一目录中,但是,未加载 .css 文件(我收到 500 错误带有原因短语的状态代码:
Reponse map is nil
下面是我的代码:
(defroutes approutes
(GET "/" reqmap
(resource-response "index.html")))
(def server (run-jetty #'approutes {:join? false, :port 3000}))
我在这里错过了什么?以及如何提供引用了其他文件(.css、.js、.jpeg 等)的 html 文件?我有一些运气(虽然我不能完全解释为什么)在 ring.middleware.resource
命名空间中使用 Ring 的 wrap-resource
中间件,尽管该函数仅在请求映射匹配静态资源时使用(并且如您所见,路由“/”与资源本身不匹配。
谢谢。
您需要添加一点中间件,它将负责从您可以select的文件夹中提供静态文件,如下所示:
;; 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 which should be found in public/resources/style.css
in your project. Any other static files should work. There's a guide in the 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
更新
我从头开始快速 运行,这应该可以帮助您找到问题所在。
创建了一个新项目:
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/ 中连接到服务器...您应该会在浏览器中看到您的页面,其中包含 It works! 消息和基本的 CSS重启。在控制台中,您很可能会看到一些异常,因为浏览器试图从您的服务器加载文件 /favicon.ico
,该文件不存在(您现在可以将其创建为空文件)。
希望对您有所帮助。