什么';在这个简单的Clojure Ring应用程序中,获取默认index.html文件的正确方法是什么? 提要

什么';在这个简单的Clojure Ring应用程序中,获取默认index.html文件的正确方法是什么? 提要,clojure,middleware,ring,compojure,Clojure,Middleware,Ring,Compojure,请注意,这个问题不是关于如何为静态文件提供服务-这是有效的-而是关于默认情况下wrap file传递索引文件的特殊情况,并且由于URL中缺少文件扩展名,错误的mime类型被分配给了内容类型头 默认情况下,如何在索引文件上获得正确的mime类型? 目前的答案还没有解决如何做到这一点,以及解决办法 我想出了一个不可伸缩的方法 工作代码 以下是使用和的应用程序的简化片段: 其目的是提供任何文件,但如果在public目录中有本地文件,则提供该文件,最后添加一个有意义的内容类型标题和相应的所有这些都非常

请注意,这个问题不是关于如何为静态文件提供服务-这是有效的-而是关于默认情况下
wrap file
传递索引文件的特殊情况,并且由于URL中缺少文件扩展名,错误的mime类型被分配给了内容类型头

默认情况下,如何在索引文件上获得正确的mime类型?

目前的答案还没有解决如何做到这一点,以及解决办法 我想出了一个不可伸缩的方法


工作代码 以下是使用和的应用程序的简化片段:

其目的是提供任何文件,但如果在
public
目录中有本地文件,则提供该文件,最后添加一个有意义的
内容类型
标题和相应的所有这些都非常有效。


问题 当我浏览到基本URL时,它确实像预期的那样提供
index.html
,但它没有得到
text/html
的内容类型,而是
application/octet stream

  • 指示
    索引文件?
    选项默认为true,这解释了没有路径的URL正确地服务于文件的原因。这似乎是一种迂腐的生活方式

  • 指示mime类型由URI中的文件扩展名推断,如果没有扩展名,则默认为
    application/octet-stream
    。由于URL不包含文件名,此函数正在“正确”执行它所声明的操作

这就引出了一个问题:如何根据响应正文的内容分配内容类型?

然而,这样做是不明智的,因为它是一个只能读取一次的可变输入流。所以这显然不是正确的方法

默认情况下,是否有更好的方法提供index.html?

难看的变通办法 目前的解决办法是使用一种特殊的路由,手动设置内容类型

更糟糕的是,如果索引文件是从 子目录

因此,我正在寻找一种中间件解决方案,而不是路由黑客

实验 探索中间件的执行顺序及其后果:

诚然,虽然我理解线程宏()在
(>xab)
转换成
(B(ax))
时,我在计算执行流通过中间软件链解析到具有路由的最终处理程序的顺序时,脑子里还是有点乱。造成这种障碍的原因是,代码可以在调用所传递的处理程序之前弄乱请求,也可以在返回之前处理响应。当我用细节来增加请求,或者在响应出来的时候,或者更复杂的情况下,根据某种条件做不同的行为时,事情需要的顺序并不“明显”地知道

e、 例如,
wrap file
是在处理程序构造响应之前还是之后发生的,因为线程中的顺序很重要?我觉得这对我来说应该更直观,而不必像我现在做的那样跑向终点

正如可能的那样,我可能比我应该做的更多地区分中间件和处理程序

交换顺序(以测试线程顺序假设)不会执行您认为的操作:

(def app                     ; THIS IS AN EXAMPLE OF BROKEN CODE - DON'T USE IT
   (-> handler
      (wrap-content-type)))  ; WRONG ORDER - DON'T DO THIS   (EXAMPLE ONLY)
      (wrap-file "public")   ; WRONG ORDER - DON'T DO THIS   (EXAMPLE ONLY)
它“有效”,但原因是错误的。
index.html
文件将被交付并“正确”呈现,但这只是因为没有添加任何内容类型。由于缺少指定的mime类型,浏览器会进行有根据的猜测,并且猜测正确

由于目标是在标题中有一个内容类型,这表明开始时的线程顺序是正确的

应该使用什么中间件来交付索引页? 因此,有了不该做什么的信息,当URL没有按名称指定默认的status index.html文件时,我应该做什么来传递该文件,因为没有要检查的扩展名?

  • WORKS-(为页面提供正确的mime类型)
  • 断开-(服务于同一页面,但内容类型错误,因此浏览器尝试下载)
有没有更好的中间件堆栈,或者甚至是推荐的,可以让我参考一下



更新2020-05-24:已提交;这可能是一个寻找贡献者的设计缺陷。

这为您提供了一个服务器,如果它位于
资源/public/
文件夹中,它将提供
index.html

(ns核心
(:require[compoure.core:refere[routes GET]]
[ring.middleware.defaults:参考[wrap defaults]]
[org.httpkit.server:as http kit]))
(def处理器
(路线)
(获取“/foo”[“Hello foo”)
(获取“/bar”[“Hello bar”))
(def应用程序
(->处理器
(包装默认值{:static{:resources“public”)
:文件“resources/public”}})
(def服务器(http工具包/运行服务器应用程序{:端口8889}))
(评论)
停止服务器
(服务器)
我使用的是
wrap defaults
,因为它提供了一种很好的方法来启动和运行服务器,同时还提供了很大的灵活性,可以根据需要进行定制

在本例中,我告诉它使用
public
作为资源文件夹,并将其
resources/public
交给文件,以便它能够正确包装要提供的文件

ring.middleware.content type
默认为
application/octet stream
,当它没有足够的信息来猜测它所服务的文件的内容类型时

如果您特别想要为文件提供服务并提供路由,那么我上面给出的答案就足够了,如果您想要显式返回a
C
(def app                     ; THIS IS AN EXAMPLE OF BROKEN CODE - DON'T USE IT
   (-> handler
      (wrap-content-type)))  ; WRONG ORDER - DON'T DO THIS   (EXAMPLE ONLY)
      (wrap-file "public")   ; WRONG ORDER - DON'T DO THIS   (EXAMPLE ONLY)