使用 clj-ajax 使用 multipart/form-data 的 Http POST 请求

Http POST request with multipart/form-data using clj-ajax

我有一个端点,我可以在其中上传带有 curl 的文本文件,如下所示:

curl -X POST -H "Content-Type: multipart/form-data" -F "file=@/resources/speciesDiffusion.tree" http://localhost:4000/continuous/tree 

现在我需要从浏览器发送类似的请求,但是

 (ajax/ajax-request
  {:uri (str "http://localhost:4000" "/continuous/tree")
   :method :post
   :params {:treefile file}
   :handler #(println %1)
   :format (ajax/text-request-format)
   :response-format (ajax/json-response-format {:keywords? true})})

给了我一个(很好地 json 转换,所以我得到了那个部分,这很好)错误响应:

[false {:status 500, :status-text , :failure :error, :response {:timestamp 1494279686227, :status 500, :error Internal Server Error, :exception org.springframework.web.multipart.MultipartException, :message Current request is not a multipart request, :path /continuous/tree}}]

此外,在浏览器中我可以看到 content-type headers 设置不正确,但我无法让它与 :format 和 :params 的任何其他组合一起工作。

cljs-ajax项目的README中有一些例子。例如:

(let [form-data (doto
                    (js/FormData.)
                  (.append "id" "10")
                  (.append "file" js-file-value "filename.txt"))]
  (POST "/send-file" {:body form-data
                      :response-format (raw-response-format)
                      :timeout 100}))

https://github.com/JulianBirch/cljs-ajax

根据我的评论,问题不在请求中,而是在发送它的 f-tion 中,即我正在读取文件内容而不是像这里发送原始对象:

(defn handle-file-upload [evt]
  (let [target (.-currentTarget evt)
        js-file (-> target .-files (aget 0))]
    (do
      (re-frame/dispatch [:post-file {:file js-file
                                                 :name (.-name js-file)}])
      (set! (.-value target) ""))))

(defn upload-button []
  (fn []
[:input {:class "none"
             :id "file-upload"
             :type "file"
             :on-change #(handle-file-upload %)}]))

其中

:post-file

是一个调用执行 POST 请求的处理程序的事件。