我试图在Pedestal 0.5.1中托管静态资产和服务.我使用::file-path指向一个目录来托管文件.如果我直接导航到文件http:// localhost:8888/index.html,这可以正常工作,但如果我转到站点的根目录http:// localhost:8888,它将提供文件application/octet-stream而不是text/html.我调整了Hello World Sample并且它具有相同的行为.
SRC /程序hello_world/server.clj
(ns hello-world.server
(:require [io.pedestal.http :as http]
[io.pedestal.http.route :as route])
(:gen-class))
(def routes
(route/expand-routes [[]]))
(def service
{:env :prod
::http/join? false
::http/routes routes
::http/file-path "/tmp/www"
::http/type :jetty
::http/allowed-origins {:creds true :allowed-origins (constantly true)}
::http/port 8888})
(defonce runnable-service (http/create-server service))
(defn -main
"The entry-point for 'lein run'"
[& args]
(println "\nCreating your server...")
(http/start runnable-service))
Run Code Online (Sandbox Code Playgroud)
开始 lein run
$ curl -i localhost:8888
HTTP/1.1 200 OK
Date: Fri, 18 Nov 2016 16:02:56 GMT
Last-Modified: Fri, 18 Nov 2016 15:10:22 GMT
Content-Type: application/octet-stream
Content-Length: 12
Server: Jetty(9.3.8.v20160314)
hello world
$ curl -i localhost:8888/index.html
HTTP/1.1 200 OK
Date: Fri, 18 Nov 2016 16:03:02 GMT
Last-Modified: Fri, 18 Nov 2016 15:10:22 GMT
Content-Type: text/html
Content-Length: 12
Server: Jetty(9.3.8.v20160314)
hello world
Run Code Online (Sandbox Code Playgroud)
有没有办法修复"/"路由以提供正确的内容类型?
要获取作为目录索引的文件的正确内容类型,请将拦截器添加io.pedestal.http.ring-middlewares/file-info到Pedestal配置中.
这要求您使用自己的默认拦截器链覆盖默认拦截器链,因此您必须包含应用程序所需的所有默认拦截器.
例如,您的服务可能如下所示:
(ns hello-world.service
(:require
[io.pedestal.http :as http]
[io.pedestal.http.ring-middlewares :as middlewares]
[io.pedestal.http.route :as route]
[io.pedestal.http.route.definition :refer [defroutes]]))
(defroutes routes
[[]])
(def service
{::http/type :jetty
::http/port 8080
::http/interceptors [http/log-request
http/not-found
middlewares/session
route/query-params
(middlewares/file-info) ; HERE
(middlewares/file "/tmp/www")
;; ... insert other interceptors ...
(route/router #(deref #'routes) :map-tree)]})
Run Code Online (Sandbox Code Playgroud)
有关您可能想要包含的其他默认拦截器的示例,请参阅default-interceptors.
这在实践中可能不会经常出现,因为许多Web应用程序使用处理程序函数来生成主页而不是返回静态文件.
对于备用解决方案,您可以为路由编写路由处理程序,该/
路由器返回index.html具有适当内容类型的内容.
Pedestal的默认拦截器堆栈包括 io.pedestal.http.ring-middlewares/file 和io.pedestal.http.ring-middlewares/content-type.
这些拦截器分别只包含Ring中间件函数 file- content 和content-type-response.
file-request返回一个java.io.File对象作为HTTP响应.
content-type-response检查请求URI以确定Content-Type标头的值.由于URI只是/默认值application/octet-stream.
相反ring.middleware.file-info(不推荐使用)检查File响应中实际对象的路径.请参阅file-info-response.
io.pedestal.http.ring-middlewares/file-info是拦截器包装器ring.middleware.file-info/file-info-response.