为啥 ring 的资源响应以 application/octet-stream 内容类型响应?

Posted

技术标签:

【中文标题】为啥 ring 的资源响应以 application/octet-stream 内容类型响应?【英文标题】:Why does ring's resource-response respond with application/octet-stream content type?为什么 ring 的资源响应以 application/octet-stream 内容类型响应? 【发布时间】:2015-06-02 23:09:15 【问题描述】:

我试图弄清楚为什么 Ring 的 resource-response 选择使用 application/octet-stream 内容类型进行响应。我最近更新了一些我一直在学习的示例代码,以便它使用更新的ring-defaults。在使用 ring-defaults 之前,此代码以 html 内容类型响应。为什么现在选择 octet-stream?

(ns replays.handler
  (:require [compojure.core :refer [GET defroutes]]
            [compojure.route :as route]
            [ring.util.response :refer [response resource-response]]
            [ring.middleware.json :as middleware]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]]))

(defroutes app-routes
  (GET  "/" [] (resource-response "index.html" :root "public"))
  (GET  "/widgets" [] (response [:name "Widget 1" :name "Widget 2"]))
  (route/resources "/public")
  (route/not-found "not found"))

(def app
  (-> app-routes
      (middleware/wrap-json-body)
      (middleware/wrap-json-response)
      (wrap-defaults api-defaults)))

对于版本号,这里是项目文件...

(defproject replays "0.1.0-SNAPSHOT"

  :url "http://example.com/FIXME"
  :description "FIXME: write description"

  :plugins [[lein-pdo "0.1.1"]
            [lein-ring "0.9.3"]
            [lein-cljsbuild "1.0.5"]]

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [org.clojure/clojurescript "0.0-3126"]
                 [org.omcljs/om "0.8.8"]
                 [ring/ring-core "1.3.2"]
                 [ring/ring-json "0.3.1"]
                 [ring/ring-defaults "0.1.4"]
                 [compojure "1.3.2"]
                 [cljs-http "0.1.29"]]

  :source-paths ["src/clj"]

  :ring :handler replays.handler/app

  :cljsbuild :builds [:id "dev"
                        :source-paths ["src/cljs"]
                        :compiler :output-to "resources/public/js/app.js"
                                   :output-dir "resources/public/js/out"
                                   :optimizations :none
                                   :source-map true]

  :aliases "up" ["pdo" "cljsbuild" "auto" "dev," "ring" "server-headless"]

  :profiles :dev :dependencies [[javax.servlet/servlet-api "2.5"]
                                  [ring-mock "0.1.5"]])

【问题讨论】:

我不确定,但我认为这与 wrap-content-type 使用 URI 上的扩展名来设置内容类型标题有关吗?可以通过向 URI 添加扩展名或手动设置内容类型 (assoc-in (resource-response ...) [:headers "Content-Type"] "text/html") 来解决此问题 我相信您的建议是正确的做法。有一个提供的函数也可以做类似的事情:ring-clojure.github.io/ring/… 是的,我避免给出答案,因为虽然我的建议会起作用,但感觉就像手动做中间件应该为你做的事情。但是如果你看一下那个函数的源代码,它会调用 header,而 header 的作用与我上面所说的差不多。 这并不是一个解决方法——我不知道为什么。 我遇到了同样的问题,并通过尝试带有 .htm 扩展名的 URL 来确认,这给出了 text/html 内容类型是响应。 .rss 相同,它给出 application/rss+xml 【参考方案1】:

这是因为api-defaults(实际上是ring.middleware.content-type)试图根据您传递给它的数据猜测您的内容类型。它使用文件扩展名来执行此操作,并且由于您使用的是resource-response,因此没有扩展名。所以默认ring.middleware.content-type使用application/octet-stream

解决方案是为响应提供您的内容类型,如下所示:

(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"))

【讨论】:

以上是关于为啥 ring 的资源响应以 application/octet-stream 内容类型响应?的主要内容,如果未能解决你的问题,请参考以下文章

为啥电脑总是显示这个,软件程序总是无响应

为啥 Wordpress 无法加载资源?它表示服务器响应状态为 404(未找到)

如何看待Linux操作系统的用户空间和内核空间

Compojure/Ring:为啥与 cookie-store 的会话在服务器重新启动后无法幸存?

为啥http请求响应没有以角度2显示?

为啥 ADAL 说证书被拒绝以响应查尔斯代理?