我认为我做对了,但我无法从 :body
输入流中获取我的 EDN。 Ring 和 Compojure 处理程序是这样的:
依赖:
[ring.middleware.params :as params]
[ring.middleware.edn :as edn]; https://github.com/tailrecursion/ring-edn
处理程序:
(defroutes ajax-example
(PUT "/ajax-example" r
(println r)
{:status 200
:headers {"Content-Type" "application/edn"}
:body "yo"}))
我把它包装成:
(def ajax-wrapped
(-> ajax-example
edn/wrap-edn-params
params/wrap-params))
println
的响应正确地表明它是 EDN 并且根据我发送的简单测试 map 内容长度是正确的,但是 map 本身无处可寻,它永远被困在 :body
的输入流中。 . 怎么弄呢?这是响应 println:
{:ssl-client-cert nil, :remote-addr 0:0:0:0:0:0:0:1, :params {}, :route-params {}, :headers {origin http://localhost:6542 , host localhost: 6542, 用户代理 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36, 内容类型应用程序/edn, cookie _ga=GA18252144882516 ;内容长度 20,引用 http://localhost:6542/,连接保持事件,接受/,接受语言 en-US,en;q=0.8,sq;q=0.6,接受编码 gzip,deflate,sdch,缓存控制 max-age =0}, :server-port 6542, :content-length 20, :form-params {}, :query-params {}, :content-type application/edn, :character-encoding nil, :uri/ajax-example , :server-name localhost, :query-string nil, :body #, :edn-params nil, :scheme :http, :request-method :put}
:body 上面没有正确粘贴,它看起来像这样:
[open corner bracket] HttpInput org.eclipse.jetty.server.HttpInput@5d969109 [end corner bracket]
使用
cljs-ajax
lib 从浏览器发送的客户端代码是:(defn ajax-send
[]
(let [push {:adder1 2 :add2 3}]
(PUT "/ajax-example"
{:format :edn
:params push
:handler ajax-result
:error-handler error-handler})))
以下是其中一个答案建议的测试输出:
hf.examples> ((-> ajax-example params/wrap-params edn/wrap-edn-params) (-> (mock/request :put "/ajax-example")
(mock/content-type "application/edn")
(mock/body "{:hello \"there\"}")))
{:status 200,
:headers {"Content-Type" "application/edn"},
:body
"{:remote-addr \"localhost\", :params {:hello \"there\"}, :route-params {}, :headers {\"content-length\" \"16\", \"content-type\" \"application/edn\", \"host\" \"localhost\"}, :server-port 80, :content-length 16, :form-params {}, :query-params {}, :content-type \"application/edn\", :uri \"/ajax-example\", :server-name \"localhost\", :query-string nil, :edn-params {:hello \"there\"}, :scheme :http, :request-method :put}"}
hf.examples>
我也试过这个:
(defroutes ajax-example
(PUT "/ajax-example" r
{:status 200
:headers {"Content-Type" "application/edn"}
:body (pr-str (dissoc r :body))}))
curl 结果独立于前端:
curl -X PUT -H "Content-Type: application/edn" -d '{:name :barnabas}' http://localhost:6542/ajax-example
{:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :params {}, :route-params {}, :headers {"host" "localhost:6542", "content-length" "17", "content-type" "application/edn", "user-agent" "curl/7.37.1", "accept" "*/*"}, :server-port 6542, :content-length 17, :content-type "application/edn", :character-encoding nil, :uri "/ajax-example", :server-name "localhost", :query-string nil, :edn-params nil, :scheme :http, :request-method
17 的
content-length
匹配通过 Curl 传递的 map 中的字符数。但是 edn-params
为零!内容在哪里? 最佳答案
编辑 :作为对更新问题的回答,wrap-edn-params 函数通过完全读取 :body InputStream 来消耗请求的主体。 Compojure 路由将请求传递给每个参数处理程序,直到返回非 nil 值。在这种情况下,作为第一个处理程序传递给路由的处理程序将消耗 :body 并且将没有 :body 值供第二个处理程序消耗,从而导致 wrap-edn-params 读取的正文值为零。
传递给环处理程序的请求可能没有将其内容类型设置为 edn。如果请求内容类型设置为 edn,wrap-edn-params function 将仅解析 edn。
此外,解析的 edn 参数将仅被 wrap-edn-params 函数放置在请求映射的 :params 和 :edn-params 键中,因此不应使用 :body 访问解析的 edn。
(require '[ring.mock.request :as mock])
(require '[ring.middleware.edn :as edn])
((-> ajax-example params/wrap-params edn/wrap-edn-params) (-> (mock/request :put "/ajax-example")
(mock/content-type "application/edn")
(mock/body "{:hello \"there\"}")))
{:remote-addr "localhost",
:params {:hello "there"},
:route-params {},
:headers
{"content-length" "16",
"content-type" "application/edn",
"host" "localhost"},
:server-port 80,
:content-length 16,
:form-params {},
:query-params {},
:content-type "application/edn",
:uri "/ajax-example",
:server-name "localhost",
:query-string nil,
:body #<ByteArrayInputStream java.io.ByteArrayInputStream@171788d8>,
:edn-params {:hello "there"},
:scheme :http,
:request-method :put}
关于clojure - 无法解析出此服务器请求中的 EDN,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30209769/