在 Clojure 中上传 POST 文件时出现 422 Unprocessable Entity 响应

422 Unprocessable Entity response when POSTing file upload in Clojure

我正在尝试模拟这个 curl 请求

curl "https://{subdomain}.zendesk.com/api/v2/uploads.json?filename=myfile.dat&token={optional_token}" \
  -v -u {email_address}:{password} \
  -H "Content-Type: application/binary" \
  --data-binary @file.dat -X POST

使用以下代码

  (POST "/uploads" request
    (let [filename (get-in request [:params "file" :filename])
          file (get-in request [:params "file" :tempfile])
          url (str "https://REDACTED.zendesk.com/api/v2/uploads.json?filename=" filename)]
        (clj-http.client/post url {:headers {"Content-Type" “application/binary”}
                                   :multipart-params [{:name "file"
                                                       :content file
                                                       :mime-type "application/binary”}]})

但我从 Zendesk 收到“422 无法处理的实体”回复。 file/tempfile 根据请求以 #object[java.io.File 0x3768306f "/var/folders/l3/7by17gp51sx2gb2ggykwl9zc0000gn/T/ring-multipart-6501654841068837352.tmp"] 的形式出现。

我玩过 clojure.java.io 强制转换(如 clojure.java.io/output-stream),如 所述,但这没有帮助。

(PS。我很确定我不需要授权,因为我可以通过 Postman 直接上传到 Zendesk。)

重新审视后,解决方案很简单。 Zendesk 期望请求主体是二进制的(如 curl 请求所示)。因此,在这种情况下,我将图像作为 base64 编码数据传递到我的服务器(就像 JSON)。

然后我使用这个库将 base64 字符串转换为字节数组:https://github.com/xsc/base64-clj

(defn byte-array-from-base64
  [base64-string]
  (base64/decode-bytes (.getBytes base64-string)))

最后,您可以简单地将字节数组作为 clj-http 库请求的主体传递给 Zendesk。

(client/post
  "https://REDACTED.zendesk.com/api/v2/uploads.jsonfilename=filename.jpg"
  {:headers {"Authorization" "Basic AUTHORIZATION_TOKEN"
             "Content-Type" "application/binary"}
   :body (byte-array-from-base64 base64-string)})