Ring/Compojure 应用中未解析请求参数

Request params not parsed in Ring/Compojure app

我正在使用 Ring 和 Compojure 编写一个 Web 应用程序,并使用 Friend 库进行授权。最近对项目做了一些改动,现在无法再获取请求参数了

我以前做的是这样的:

; Routes definition
(defroutes app-routes
  (POST "/*.do" request 
    (insert-data (:params request))))

; Middlewares
(def secured-routes
  (handler/site
    (-> app-routes
        wrap-params
        (friend/authenticate friend-params-map))))

和 form/URL 参数将被解析为 Clojure 映射。现在这似乎不起作用,(:params request) 包含

形式的地图
{:* <request-url>}

用一个 :* 键。如果我尝试 (println request),得到一个包含很多键值对的 Clojure 映射,其中有

:body #object[org.eclipse.jetty.server.HttpInputOverHTTP 0x6ef9a9e1 HttpInputOverHTTP@6ef9a9e1]

似乎包含请求数据,对吗?但是我该如何获取这些呢?

之前我只是使用如上所述的 wrap-params 中间件,并且它有效。

一种有效的方法是在每个处理程序中调用 (body-string request),这将 return 请求主体的字符串化版本。但是为每个 url 处理程序获得一个自动解析的 Clojure 映射会很棒。显然,我错过了一些东西。

有人可以指点一下吗?我也很乐意了解更多如何自己调试此类处理程序问题 - 也就是说,调试中间件链并找出 wrap-params 未被调用或被不正确调用的原因。

谢谢!

更新: 根据@nberger 的评论,我尝试将 secured-routes 定义更改为:

(def secured-routes
  (-> app-routes
      (wrap-defaults site-defaults)
      (friend/authenticate friend-params-map)))

但现在登录页面根本不起作用(身份验证停止工作)。按照评论中的建议将 wrap-defaults 移动到 friend/authenticate 之后,Friend 以大字体抱怨 Invalid anti-forgery token (???)

我发现了问题。在前端代码中,POSTs to *.do 被修改为发送application/json content-type。下面是 jQuery 的 ajax 调用:

$.ajax({ 
  url: '/saveInput.do',
  type: 'POST',
  contentType: 'application/json; charset=UTF-8',
  data: JSON.stringify(formValues),
});

我修改为

$.ajax({ 
  url: '/saveInput.do',
  type: 'POST',
  data: formValues,
});

现在可以使用了。此外,可以通过包含来自 ring-jsonwrap-json-params 中间件来保留具有 JSON 内容类型的原始 Ajax 调用,因此路由定义最终变为:

(def secured-routes
  (-> app-routes
      (friend/authenticate friend-params-map)
      (wrap-defaults (assoc-in site-defaults [:security :anti-forgery] false))
      wrap-json-params))

我选择了后者。 @nberger - 谢谢你的帮助!