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 (???)
我发现了问题。在前端代码中,POST
s 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-json 的 wrap-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 - 谢谢你的帮助!
我正在使用 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 (???)
我发现了问题。在前端代码中,POST
s 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-json 的 wrap-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 - 谢谢你的帮助!